TIA PUT funktioniert trotz grüner Verbindung nicht

sps_bond

Level-2
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Liebe SPS Kollegen,


ich verzweifele gerade an der Put Funktion von Siemens. ICh möchte Daten von einer S7-1200 in eine zweite S7-1200 senden über PUT.
Habe übers Wochenende viel probiert aber der Status der Funktion zeigt weder Done noch einen Error an. Die konfigurierte Verbindung wird grün angezeigt sobald ich Online gehe.

Aber in der enstprechenden DB2 mit den entsprechenden Offsets auf der Ziel CPU kommt nichts an und es wird auch keine Fehler angezeigt. Optimierter Bausteinzugriff ist deaktiviert und die Freigabe für PUT in der Ziel CPU unter Schutz ist aktiviert.

Habt ihr ne Idee woran ich hier scheitere bzw. was ich übersehe?

Einen schönen Montag euch allen!
 

Anhänge

  • 1.jpg
    1.jpg
    70,9 KB · Aufrufe: 59
  • 2.jpg
    2.jpg
    33,3 KB · Aufrufe: 44
Zuletzt bearbeitet:
Req startet mit einer Flanke am Eingang.
Nach Fertigstellung ist Done oder Error einen Zyklus lang True, danach erst kann man Put wieder mit einer neuen Flanke starten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habt ihr ne Idee woran ich hier scheitere bzw. was ich übersehe?
Mit einem Klick auf F1 kommst du in die Hilfe zu dem Baustein. Und dort wird drin stehen,
dass an REQ eine positive Flanke benötigt wird. Weitere Hinweise hat dir Ralle auch noch gegeben.
 
Sauber Jungs, das war es. Habe eine Clock0,5Hz eingesetzt unter Req und jetzt geht es! Tausend dank, so einfach kann es manchmal gehen!
 
Danke für den Hinweis, habe ich so umgesetzt und als Startwert für Req TRUE in der DB gesetzt.
Anhang anzeigen 53803

Was ich für eine ganz schlechte Idee halte, im Aufruf den eigenen Instanz DB zu verwenden und auf einen Instanz DB zu schreiben.

PS:
Was ist deine Lösung, wenn bei einem CPU Neustart DONE und ERROR auf 0 steht?
Dann wird deine Kommunikation nicht starten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für den Hinweis, habe ich so umgesetzt und als Startwert für Req TRUE in der DB gesetzt.
Gaaanz schlechte Idee. Wenn schon beim allerersten Aufruf <Instanz>.REQ = 1 ist, dann kann der PUT gar keine steigende Flanke erkennen.
Am besten auch noch die am REQ angeschaltete Variable auf "nicht remanent" setzen.

Beim Aufruf der PUT-Instanz die selben Variablen aus der Instanz zu verschalten ist zwar eigentlich überflüssig aber nicht schlimm. Sowas macht man oft bei Aufrufen, um die Werte direkt im Programmcode am Baustein beobachten zu können (z.B. in KOP/FUP).

Harald
 
Danke für den Hinweis, habe ich so umgesetzt und als Startwert für Req TRUE in der DB gesetzt.

Mal abgesehen davon dass hier ein IF keinen Sinn macht.
Ich empfehle dir dringends mit einer Flanke von Done und Error zu arbeiten und damit den Req zurückzusetzen. Ich Mache üblicherweise noch einen Angsttimer rein der bei mehrsekündigem Anstehen von Req diesen auch wieder resetiert.
Damit umgehst du alle möglichen Hänger.
 
Code:
"Put_DB".REQ := "Put_DB".DONE OR "Put_DB".ERROR;
Diese Logik (egal ob mit oder ohne IF) ist nicht gut. Die funktioniert ja erst NACH einem REQ-Auftrag, daher wohl die Idee mit dem Startwert TRUE.

Bessere Logik:
Code:
"Put_DB".REQ := NOT("Put_DB".DONE) AND NOT("Put_DB".ERROR) AND NOT(req_timeout.Q);
req_timeout ist der von vollmi erwähnte "Angsttimer"

Harald
 
Code:
Bessere Logik:
[CODE]
"Put_DB".REQ := NOT("Put_DB".DONE) AND NOT("Put_DB".ERROR) AND NOT(req_timeout.Q);
req_timeout ist der von vollmi erwähnte "Angsttimer"

noch etwas Sicherere Logik
Code:
"Put_DB".REQ := NOT(FP_Error.Q OR FP_Done.Q OR TON_REQ.Q);
Ich schmeiss Done und Error immer auf eine Flanke. Denn Manche Bausteine lassen Done oder Error einfach Anstehen bis man den Req neu antriggert.
Wenn man den REQ also nur auf flanken triggert, ist es egal ob DONE/Error anstehend bleiben oder nur einen Zyklus lang anstehen. Dann ist es irgendwann egal ob man PUT/GET / BSEND/RECV oder Modbus oder was auch immer braucht. Mit der drumherumkonstruktion funktioniert dann einfach alles.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
"Put_DB".REQ := "Put_DB".DONE OR "Put_DB".ERROR;
Diese Logik (egal ob mit oder ohne IF) ist nicht gut.

Ja, das stimmt. Ich wollte es ihm nur als reines Beispiel zeigen, wie man so ein IF ELSE Konstrukt einfacher schreiben kann.
 
Zuletzt bearbeitet:
Verstehe ich die Funktion so richtig, dass REQ getriggert wird wenn entweder Done oder der Error oder der Angsttimer ausgelaufen ist? Auf wieviele Sekunden stellt man den Erfahrungsgemäß?
 
Verstehe ich die Funktion so richtig, dass REQ getriggert wird wenn entweder Done oder der Error oder der Angsttimer ausgelaufen ist? Auf wieviele Sekunden stellt man den Erfahrungsgemäß?

Kommt auf die Variante an. Bei mir wird REQ immer auf TRUE gehalten, ausser ein Done, Error oder der Angsttimer kommt, dann wird REQ genau für einen Zyklus auf False gesetzt. Damit kriegt man die Steigende Flanke am REQ beim nächsten Zyklus und der Baustein erkennt sie immer.
Das ist z.B. sinnvoll, wenn man Bausteine Hat die man mit sowas wie nem REQ antriggert, die aber sofort ihre Arbeit einstellen wenn REQ auf FALSE geht.
Darum REQ True bis der Baustein fertig ist, dann einen Zyklus False und sofort wieder true.

3 Sekunden für den Angsttimer ist ein relativ sicherer wert. Aber natürlich kann das z.B. bei einer sehr langsamen Verbindung mit sehr vielen Daten auch länger ausfallen. Also wie so oft (kommt drauf an)
Der kann also auch lang eingestellt sein. Er soll ja nicht regelmässig notwendig sein, der ist mehr dazu da die Situation zu retten und des Programmierers Gesicht zu wahren ;-) z.B. Instanzüberschrieben wurde, CPU neustart und nicht abgefangen etc.
Es gibt diverse Möglichkeiten warum ein Baustein weder ein Done noch ein Error liefert und die fängt man mit dem Angsttimer ab und man spart sich ein bisschen drumherumwerk wie Initialisationsbits und dergleichen.

Ausserdem willst du vielleicht nicht den maximal möglichen Sendetakt ausnützen, das kann dir nämlich auch den Rückwandbus zumachen oder dein Netzwerk zumüllen. Dann macht ein Zeitgeber der den Request bedingt setzt wieder Sinn.
Das sind dann wieder IF_Thens
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen Dank für die Anmerkungen. Habe jetzt mit zwei Timern meine Lösung umgesetzt. Der Put_Angsttimer erzeugt alle 3 Sekunden eine Flanke und setzt sich mit dieser auch zurück. Der Put1_Timer triggert den Put Request alle 250ms außer er wird von Done, Error oder dem Angsttimer zurückgesetzt. Hoffe ich habe damit alles richtig verstanden und für die Zukunft gelernt :D1.jpg
 
Vielen Dank für die Anmerkungen. Habe jetzt mit zwei Timern meine Lösung umgesetzt. Der Put_Angsttimer erzeugt alle 3 Sekunden eine Flanke und setzt sich mit dieser auch zurück. Der Put1_Timer triggert den Put Request alle 250ms außer er wird von Done, Error oder dem Angsttimer zurückgesetzt. Hoffe ich habe damit alles richtig verstanden und für die Zukunft gelernt :D

noch nicht so ganz. Wenn du den angsttimer als takt programmierst, setzt du alle drei sekunden den Req Zurück unabhängig von done oder error. Du willst mit diesem timer aber nur req zurücksetzen wenn dieses aus gründen zu lange ansteht.
den 250 ms timer startest du wenn das req auf false ist, damit setzt du dann den req.
in dieser konstellation empfehle ich dir req mit einem if zu setzen und zurückzusetzen. Das ist einfach und übersichtlich.
 
Zurück
Oben