Step 7 AG_SEND schwankende Fehlermeldungen

Azrael666

Level-1
Beiträge
239
Reaktionspunkte
18
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ich habe hier eine CPU315-2 DP mit angeschlossenem CP343-1 IT.
Mit diesem CP verschicke ich per AG_SEND Telegramme an einen SQL Server.

Das Datensenden funktioniert auch und der Server empfängt die Daten auch so wie er es soll.

Das Problem ist, sobald der AG_SEND angetriggert wird, schwankt der Status immer zwischen 8181 und 8183 hin und her (bei der 8183 gibt er logischerweise auch immer einen ERROR raus). Das dauert ca. 1-2 Sekunden, dann sind die Daten verschickt.

Als Zusatzinfo: Ich verwende zwei AG_SEND. Jeder hat seine eigene Verbindung projektiert, die bis auf die Verbindungs-ID, identisch aufgebaut sind. Beide Verbindungen sind im NetPro auch als I.O. gekennzeichnet.

Hat jemand eine Idee woran es liegen könnte?

MFG Azrael
 
Betreibst du die beiden AG_Send-Aufrufe unabhängig voneinander - oder ist der Aufruf des Einen verriegelt solange der Andere noch läuft ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Betreibst du die beiden AG_Send-Aufrufe unabhängig voneinander - oder ist der Aufruf des Einen verriegelt solange der Andere noch läuft ?

Beide AG_SEND werden gleichzeitig getriggert. Der erste AG_SEND läuft über die ID 1 und der zweite über die ID 2.

Das Problem besteht aber auch wenn ich nur einen verwende.
 
Zuletzt bearbeitet:
OK ... triggerst du den Einen oder Anderen eventuell schon wieder obwohl er noch nicht durchgelaufen ist ...?
 
OK ... triggerst du den Einen oder Anderen eventuell schon wieder obwohl er noch nicht durchgelaufen ist ...?

Ich verwende den AG_SEND in einem SCL Baustein. Nach Ablauf einer bestimmten Zeit setze ich mir den Merker "Connect" auf True und mit SENDEN_DONE wieder auf False und die Zeit wird wieder von neuem gestartet.
Von daher ist der Trigger wärend des Sendevorgangs auf True. Aber da der AG_SEND auf eine Flanke wartet, sollte das eigentlich passen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... das meinte ich nicht ... aber du hast mir meine Frage schon beantwortet ... 8)

Du solltest kontrollieren, on der SEND seinen Auftrag WIRKLICH abgearbeitet hat ...
Ich vermute, dass du dem Baustein einen erneuten Start gibst obwohl er seinen letzten (davorliegenden) Sende-Auftrag noch nicht abgeschlossen hat.
Darauf deutet auch dein Status hin : 8181 heißt "Auftrag läuft" und 8183 heißt "Auftrag konnte nicht angenommen werden"
Ich denke, du solltest hier auf den Status warten, der sagt, dass der Baustein (wieder) bereit ist ...

Gruß
Larry
 
... das meinte ich nicht ... aber du hast mir meine Frage schon beantwortet ... 8)

Du solltest kontrollieren, on der SEND seinen Auftrag WIRKLICH abgearbeitet hat ...
Ich vermute, dass du dem Baustein einen erneuten Start gibst obwohl er seinen letzten (davorliegenden) Sende-Auftrag noch nicht abgeschlossen hat.
Darauf deutet auch dein Status hin : 8181 heißt "Auftrag läuft" und 8183 heißt "Auftrag konnte nicht angenommen werden"
Ich denke, du solltest hier auf den Status warten, der sagt, dass der Baustein (wieder) bereit ist ...

Gruß
Larry

:D achso, doch doch. Der Baustein ist danach fertig mit senden. Ich bekomme ja auch die Meldung Senden_Done und danach ist der Status ja auch wieder bei 0000.
Erst mit dem Senden_Done wird Connect wieder auf False gesetzt und das Zeitintervall startet wieder von vorne (aktuell alle 30 Sekunden wird der Baustein angetriggert)
 
naja ... deine Status-Meldungen sagen (mir) aber etwas Anderes ...
Ich würde dann Folgendes erwägen (bzw. ich würde es genau so machen) :

- Schrittkette für den Kommunikations-Ablauf
- 1. Send_1 starten
- 2. warten bis Send_1 läuft -> Trigger wegnehmen
- 3. warten bis Send_1 fertig
- 4. kurze Zeitverzögerung
- 5. Send_2 starten
- 6. warten bis Send_2 läuft -> Trigger wegnehmen
- 7. warten bis Send_2 fertig
- 8. Zeitverzögerung
- Durchlauf wiederholen ...

Vielleicht hast du ja Lust, das mal so auszuprobieren ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hab jetzt mal den Trigger geändert. Jetzt bekommen die AG_SEND ihren Sendeanstoß nur als Flanke. Jetzt sieht es wie folgt aus.
Wenn ich nur einen AG_SEND verwende, ist das Problem verschwunden. Sobald ich aber wieder beide in Benutzung habe, ist das Problem wieder da, auch wenn beide zeitversetzt senden.
Hängt das vieleicht damit zusammen, dass ich in beiden Verbindungen den selben Port projektiert habe?
 
Ist der Empfänger der Gleiche? Sind alle Parameter die Gleichen?
Wenn ja, warum rufst du AG_SEND 2 Mal auf? Macht es nicht mehr Sinn das zu Schickende zu ändern und dann mit einem AG_SEND zu senden?

Was heißt zeitversetzt bei dir? Per Timer oder per Freigabe durch den Baustein? Ein Timer zur "Sperre" einzusetzen ist keine gute Idee, wie Larry Laffer schon angesprochen hat.
Lieber die Rückmeldung des Bausteins auswerten und dann eine "Sicherheitszeit" noch oben drauf. Dann kann man sicher sein, dass die Verbindung für ein neues Anstoßen frei ist.
 
Zuletzt bearbeitet:
Ne, ich glaube ich hab es falsch erklärt :cool:

Also ich habe 2 verschiedene FBs. Beide versenden Strings per AG_SEND und zwar an den selben SQL Server. Deswegen sind die beiden Verbindungen identisch (bis auf die Verbindungs-ID). Jeder FB verschickt seine Daten alle 30 Sekunden.

Ich poste hier mal den Code-Auszug.

Code:
IF SEND_STATUS = W#16#8181 AND CONNECT THEN SEND_BUSY := TRUE;    
ELSE IF CONNECT AND SEND_BUSY AND SEND_BUSY_EXT AND SEND_STATUS = W#16#0000 THEN SEND_BUSY := FALSE;
    END_IF;
END_IF;


IF (SEND_STATUS = W#16#0000 OR SEND_STATUS = W#16#8183) AND CONNECT AND SEND_BUSY THEN SEND_REPEAT := TRUE;
    ELSE SEND_REPEAT := FALSE;
END_IF;


AG_SEND(ACT := CONNECT AND (NOT SEND_BUSY OR SEND_REPEAT) AND NOT SEND_BUSY_EXT  // IN: BOOL
        ,ID := WORD_TO_INT(ID) // IN: INT
        ,LADDR := LADDR // IN: WORD
        ,SEND := TempPointerSend  // IN: ANY
        ,LEN := LEN (SENDE_STRING) // IN: INT
        ,DONE := SEND_DONE // OUT: BOOL
        ,ERROR := SEND_ERROR // OUT: BOOL
        ,STATUS := SEND_STATUS // OUT: WORD
        ); // VOID
        
IF SEND_DONE THEN 
    CONNECT := FALSE;
    SEND_BUSY := FALSE;
    END_IF;

Ich habe jetzt beide AG_SEND gegeneinander verriegelt, so dass nur einer senden darf. Ich hab zum Test auch mal beiden Verbindungen unterschiedliche Ziel-Ports gegeben. Die Schwankungen sind trotzdem geblieben.

Was mir aber jetzt gerade aufgefallen ist, ist dass beide Verbindungen laut NCM-Diagnose die ganze Zeit aufgebaut sind und genau zu dem Zeitpunkt wenn der AG_SEND Daten schickt, die entsprechende Verbindung plötzlich abgebaut ist. Nach dem Sendevorgang ist sie dann sofort wieder aufgebaut.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und dieser Code wird ist in einem FB eingebettet und wird zweimal aufgerufen?

Gehen wir das ganze doch einmal Zyklus für Zyklus durch. Im ersten Zyklus wird im ersten Code der AG_SEND gestartet. Die Auswertung des Status erfolgt aber nach dem Start des AG_SEND nicht mehr, SEND_BUSY (ist doch der FB-Ausgang?) wird nicht an gehen. Zumal ich mir nicht sicher wäre, ob nach der ersten Ausführung des AG_SEND der Status gleich auf 0x8181 geht. Ich hätte wie Larry nochmal ne Sicherheitszeit in Form eines TON rein gebastelt.
Jedenfalls wird der zweite FB mangels SEND_BUSY_EXT (der Eingang des FBs?) auch versuchen den zweiten AG_SEND zu starten, was natürlich nicht klappt. Während der erste nun sendet, bleibt der zweite im Fehlerzustand. Ist der erste fertig, bräuchte der zweite wahrscheinlich wieder eine Flanke am ACT, um starten zu können. Nun weiß ich nicht, wie dein aufrufendes Programm aussieht aber wahrscheinlich lässt Du einfach an beiden FBs CONNECT wieder aus- und einschalten und wie sind wieder beim ersten SPS-Zyklus.

Probier doch einmal Larrys Vorschlag mit der Ablaufsteuerung und sag uns, ob das klappt.

MfG
RoMe
 
Danke an Krumnix und RoMe87 für die Bestätigung meines Vorschlages (Der wird auf jeden Fall funktionieren, da ich etwas Ähnliches in der Vergangenheit selber schon so gelösst habe).
Das Poblem, das wir hier haben, ist, dass es sich hier nicht um einen synchronen Dienst handelt (also etwas, dass sofort ausgeführt wird und das erst nach seiner Beendigung eine Weiterführung des Programms gestattet) sondern um einen asynchronen Dienst (es wird also gestartet und im Hintergrund abgearbeitet und meldet dann irgendwann, also nach möglicherweise ettlichen Programmzyklen, seine Beendigung).

Gruß
Larry
 
Ich poste hier mal den Code-Auszug.

Code:
IF SEND_STATUS = W#16#8181 AND CONNECT THEN SEND_BUSY := TRUE;    
ELSE IF CONNECT AND SEND_BUSY AND SEND_BUSY_EXT AND SEND_STATUS = W#16#0000 THEN SEND_BUSY := FALSE;
    END_IF;
END_IF;
Vieeel zu kompliziert/umständlich gedacht. Den AG_SEND-STATUS-Ausgang braucht man nicht für die Ablaufsteuerung (sondern nur für Fehleranalyse). Für den Ablauf brauchen nur DONE und ERROR (und ACT) ausgewertet (bzw. gesteuert) zu werden.

Übrigens ist es egal, wieviele AG_SEND-Instanzen man aufruft, Hauptsache, es wird für jede Verbindungs-ID nur 1 Instanz verwendet bzw. nur Instanzen mit der selben Verbindungs-ID müssen verriegelt werden.

Harald
 
... es gibt zwar laut Aussage des TE 2 verschiedene Verbindungs-ID's - es ist aber beide Male der gleiche Empfänger (und wir wissen nicht, was der tut bzw. wie der arbeitet).
Alleine aus der Beschreibung von Azrael kann es sich hier nur um ein Problem des Zeitverhaltens handeln ...

Aber ...
@Harald:
was macht dich da in deiner Aussage so sicher ...?
 
Hallo Leute,
erst mal vielen Dank für die vielen Tipps :). Ich habe jetzt erst mal folgendes Ausprobiert. Ich habe jetzt zum testen den FC5 AG_SEND normal im KOP programmiert. Und zwar nur einen einzigen.
Dann habe ich den ACT-Eingang mit einem Merker und Flanke beschaltet, so dass der Eingang nur einen Impuls bekommt. Jetzt passiert folgendes:
Beim ersten absetzten des Impulses passiert gar nichts. Wenn ich jetzt die Flanke wiederhole, wird alles ordentlich und ohne irgendwelche Fehlermeldungen verschickt (SENDEN_DONE kommt). Wenn ich jetzt die Flanke erneut antriggere geht das Spiel wieder von vorne los.
Ich muss im Grunde genommen 2 mal triggern damit was passiert.

Mein zweiter Versuch war, den ACT-Eingang mit einem Merker UND NICHT SENDEN_DONE zu beschalten. In diesem Versuch tritt genau mein Anfangs beschriebenes Phänomen mit den springenden Stati auf.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kann das gerade nicht nachstellen, habe es aber so in Erinnerung :
DONE kommt nur für einen Zyklus (irgendwann nach dem Antriggern).
Du kommst also auch an der Stelle um irgendetwas, dass sich merkt, was du jeweils tust, nicht herum (Schrittkette ?).
 
So hier ist mal ein Screenshot vom Testaufbau. Wie gesagt hier bei diesem Aufbau funktioniert es reibungslos, allerdings nur jeden 2ten Impuls.

Unbenannt.png

@Larry: Das mit dem Done ist ja kein Problem. Ich meinte nur das mein ursprüngliches Problem nichts mit der Anzahl der AG_SEND zu tun hat, sondern anscheinend mit der Art und Weise wie dieser Baustein angetriggert wird.
 
Zurück
Oben