Step 7 AG_SEND schwankende Fehlermeldungen

Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bin nicht der Experte was AG_SEND angeht.
Ich habe aber eine Anlage wo das funktioniert. Vielelicht hilft das weiter?Anhang anzeigen 35376Anhang anzeigen 35377


So wie du das im Netzwerk 2 hast, hab ich das auch schon versucht in SCL zu bauen. Allerdings verschickt er dann gar nichts mehr.

Im Moment hab ich meinen Code so umgebaut, leider auch nicht wirklich zufriedenstellend.

Code:
IF CONNECT AND NOT SEND_BUSY_EXT THEN SEND_BUSY := TRUE;
END_IF;


PulsePosCon := SEND_BUSY AND NOT EdgeFlagPosCon;
EdgeFlagPosCon := SEND_BUSY;


SEND_REPEAT_TON (IN:= SEND_BUSY AND NOT SEND_REPEAT_TON.Q, PT:= T#1S);


PulsePosREPEAT := SEND_REPEAT_TON.Q AND NOT EdgeFlagPosREPEAT;
EdgeFlagPosREPEAT := SEND_REPEAT_TON.Q;


AG_SEND(ACT := PulsePosCon OR (SEND_BUSY AND PulsePosREPEAT) // 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;
 
@Tigerente:
Naja ... im Grunde ist dein Code so eine Art "indirekte Schrittkette" - aber klar ... so wird es funktionieren.

@Azrael:
Wie du von dem Done auf den Trigger kommst sehe ich da allerdings nicht. Aber vielleicht nimmst du wirklich mal den "wirklich" schrittweisen Ablauf als Grundlage ... 8)

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
zu deinem Beitrag #21 :
Durch das mit dem TON blicke ich gar nicht durch. Du solltest mit dem DONE einen Trigger für den Timer machen. Der Timer.Q kann dann dieses Trigger-Bit (eine Stat-Variable wieder rücksetzen und den TTrigger für den FC wieder setzen).
Aber nochmal ... warum machst du nicht einfach eine Schrittkette davon ? Dann könntest du es schön debuggen und wir würde wahrscheinlich schon gar nicht mehr darüber reden ...

Gruß
Larry
 
@Tigerente: Danke für die Info. Ich versuch das mal nachzubauen.

@Larry: Das mit der Schrittkette leuchtet mir ein
:). Allerdings ist das Problem dass die beiden FBs mit den jeweiligen AG_SEND unabhängig voneinander arbeiten. D.h. der eine sendet alle X Sekunden und der andere alle Y Sekunden. Wobei dann noch erschwerend hinzukommt, dass einer der beiden FBs nicht nur alle X Sekunden verschickt sondern auch bei jeder Änderung an einem der Eingänge ( hat 6 Bool Eingänge ).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das, was Tigerente dir gepostet hat ist im Grunde die Hälfte dessen, was ich im Beitrag #8 schon dargestellt habe. Ob man jetzt mit dem Status oder den Bits arbeitet ist dabei mal offen ... entscheidend ist, dass die Dinge sich nicht überlappen.
Damit hättest du dann einen Kommunikations-Ablauf.

Zu deinem Gesamt-Ding :
Beschreib doch mal genau, was du zu tun beabsichtigst - also was willst du wann verschicken ?
Ich würde das vom Grund-Ansatz so aufsetzen :
- es gibt einen Baustein (FB) der die Kommunikation übernimmt.
- falls du manuell (also per Startbit oder so) entscheiden möchtest, wann was versandt wird dann für die für jede Aufgabe z.B. In-Bit's vorsehen.
- der Baustein hat intern eine Schrittkette mit alternativen Zweigen für die unterschiedlichen Aufgaben.
- setzt du nun einen der Auftrags-IN's so wird dieses Bit zunächst erstmal nur gespeichert. Dieses intern gespeicherte Bit lösst dann den jeweiligen Sende-Vorgang aus, sobald der Baustein dafür bereit ist (nichts anderes mehr tut). So kannst du dann auch theoretisch mehrere Bit's gleichzeitig setzen - sie würden dann sequentiell abgearbeitet.

Was hältst du davon ?

Gruß
Larry
 
Ich werde das am Montag nochmal weiter versuchen. Aktuell habe ich festgestellt, dass es mit nur einem AG_SEND genauso funktioniert wie Tigerente das beschrieben hat. Bis auf die Tatsache, dass es in SCL anscheinend nicht immer funktioniert.
Bei mehreren AG_SEND scheint es wohl so zu sein, dass ich sie nicht nur nicht gleichzeitig ansteuern darf, sondern dass auch der gesamte FC5- Aufruf nicht aktiv sein darf.

@ Larry: der Rest meines Bausteins funktioniert ja soweit. Ich habe die FBs ja schon komplett fertig für CPUs die eine integrierte Ethernet Schnittstelle haben. Dort verwende ich allerdings die TCON, TSEND und TDISCON.
Die kann ich aber leider bei einem CP nicht benutzen, sondern muss auf den AG_SEND umsteigen.

Um das Ganze grob zu umschreiben, mein Baustein sammelt Informationen von außen, baut diese zu einem String zusammen und versendet sie an einen SQL Server. Von diesen Dingern hab ich 2 Varianten, der eine Verarbeitet Bool- und der andere Integer-Informationen.
Wie gesagt, das Ganze habe ich für PN/DP Geräte fertig und jetzt muss ich noch die Variante für CP300 bzw CP400 Geräte bauen.
 
Naja ... für den von mir angedachten Baustein ist die Art der Kommunikation eigentlich nebensächlich. Man könnte das Ganze sogar so weit treiben, dass du per IN-Parameter des FB's festlegst wohin die Reise gehen soll.
Ich verstehe aber, dass ich hinsichtlich des Erstellen von Bausteinen eine komplett andere Denkweise habe wie du. Falls du an meinem Ansatz wirklich interessiert bist dann werde ich dir gerne dabei helfen - aufzwingen werde ich ihn dir natürlich nicht (das ist ja auch nicht der Sinn eines Forums wie dieses ...

Gruß
Larry

Nachsatz :
Ich versuche eigentlich immer ganz gerne in sich geschlossene Objekte zu erzeugen ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen alle zusammen,

@Larry: :) erst mal, ich finde es super dass du, soweit ich es gesehen habe, zu fast jedem Problem dass jemand hat , gute Lösungen parat hast *Daumen hoch* und immer mit Rat und Tat zur Seite stehst.
Dein ursprünglicher Lösungsansatz war es ja das ganze wie eine Schrittkette ablaufen zu lassen. Was sich mir jetzt allerdings nicht erschließt ist, wie ich das FB übergreifend realisieren soll, vorallem weil beide FBs völlig unabhängig voneinander arbeiten. Leider kann ich auch nicht beide FB-Funktionalitäten in einem FB zusammenfassen, weil ich dadurch Probleme mit Arbeitsspeichergröße, Stackspeicher, etc. bekomme.

Aber ich weiß jetzt zumindest schonmal, dass mein ursprünglicher Fehler daher kommt, dass sich beide AG_SEND irgendwie gegenseitig ins Gehege kommen. Jetzt muss ich nur noch eine Lösung finden das zu verhindern.
 
Hallo,

eigentlich kommt es nicht darauf an, ob du alles in einen Baustein packst oder das getrennt in gekapselte Bausteine schreibst.
Sofern der AG-SEND wirklich nicht in einer anderen Instanz angetriggert werden darf, wenn ein Sendeauftrag noch aktiv ist, musst Du das halt verriegeln.

Ganz grob gesagt baust Du eine Schrittkette die darauf wartet, dass eine Sendeanforderung kommt. Meinetwegen A oder B.
Die Schrittkette springt in den "Sendeschritt" und wartet auf "ERROR" oder "SEND_DONE". Erst danach kann erneut gesendet werden.
In diese Schrittkette solltest Du natürlich noch einbauen, ob A/B z.B. im Wechsel senden, wenn beide eine Sendeanforderung absetzen.
Denkbar wäre auch eine Priorisierung für einen der Sender. Je nachdem was Du brauchst.
 
Hallo Leute,

ich hab jetzt meinen Code für die Sache etwas angepasst. Sieht aktuell so aus:

Code:
IF SEND_BUSY AND SEND_BUSY_EXT THEN SEND_BUSY := FALSE;    
END_IF;


IF CONNECT = FALSE THEN 
        SEND_BUSY := FALSE;
        SEND_DONE := FALSE;
END_IF;


IF CONNECT AND NOT SEND_BUSY_EXT THEN
        
    PulsePosCon := CONNECT AND NOT SEND_BUSY;


    IF NOT SEND_BUSY THEN
        SEND_BUSY := TRUE;
    END_IF;
    
    //SEND_TOF (IN:= PulsePosCon, PT:= T#5ms);


    AG_SEND(ACT := PulsePosCon  // 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


    TON_WDH (IN := (CONNECT AND SEND_BUSY AND SEND_STATUS = W#16#0000) OR SEND_ERROR,
            PT := T#150ms);


    IF TON_WDH.Q THEN SEND_BUSY := FALSE;
    END_IF;


    IF SEND_DONE AND SEND_BUSY AND NOT SEND_ERROR THEN 
    CONNECT := FALSE;
    END_IF;


END_IF;

Das Ganze läuft auch soweit, bis eben auf die Tatsache, dass mein ursprüngliches Problem zwar deutlich weniger geworden ist, allerdings nicht völlig verschwunden ist, obwohl beide AG_SEND gegeneinander verriegelt sind.
Irgendwie scheint es dass der AG_SEND nichtt zu mögen, wenn mehrere seiner Sorte "Enabled" sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mal eine kurze Anleitung, was ein AG_SEND bei einer 300er macht (nicht bei der 400er):
AG_SEND versorgt im Grunde erstmal den Ladespeicher deiner CP mit Nutzdaten. Bei einer 300er können dafür pro Zyklus/Aufruf maximal 240 Byte übertragen werden. Wenn dein Datenbereich größer ist, benötigt der Baustein 2 Aufrufe/Zyklus oder mehr.
Manchmal gibt es Spezies, die den Baustein 2 Mal pro Zyklus aufrufen, um die Daten an den CP zu übergeben, was aber zu stark erhöhten Zykluszeiten führt. Daher lieber so realisieren, dass ein Übergeben der Nutzdaten von 240 Byte nur einmal
pro Zyklus erfolgt.
Beim Setzen von ACT = 1 übernimmt der Bausteine alle Informationen, welche ihm übergeben wurden und beginnt mit dem Befüllen des Speichers der CP. Dabei wird DONE auf Null gesetzt.
Nun muss ACT = 0 werden, damit die weitere Abarbeitung des Sendeauftrags erfolgt. DONE bleibt in diesem Fall auch weiterhin auf 0. Wenn also mehr als 240 Byte anstehen, werden im 2. Zyklus der nächste Bereich an Nutzdaten an die CP übergeben.
Bin mir nicht sicher, aber die IT kann bis zu 2048 Byte aufnehmen. Müsste man aber nochmals überprüfen.
Wenn alle Nutzdaten in den CP geschrieben wurden, wird der Sendeauftrag an den Empfänger gestartet. In dieser Zeit ist DONE weiterhin auf 0. Nach übertragen der Daten an den Empfänger, was auch mal 2-3 Zyklen dauern kann, meldet die CP
dies und der Baustein setzt DONE = 1.
Danach kann der Baustein wieder einen Auftrag annehmen.

Sollte nun in der Zwischenzeit der Baustein nochmals aufgerufen werden, und die Paramater passen nicht zu den Daten, welche beim 1. Aufruf übergeben wurden, gibt der Baustein in diesem Moment einen Fehler zurück.
Solange also der Baustein mit dem 1. Auftrag beschäftigt ist, nimmt einer keinen 2. an. Je nach Kommunikationspartner kann es auch mal länger dauern, bis alles übertragen ist.

Wenn nun also sporadisch hier ein Fehler auftaucht, stoßt du wohl zu einem Zeitpunkt einen 2. Auftrag an, in welchem der Baustein oder die CP mit dem aktuellen noch nicht fertig ist.
 
Cool, vielen Dank für die ausführliche Erklärung zu dem Baustein. Das gibt schonmal einen besser Einblick in das Ding.

Wenn ich mich jetzt aber nicht täusche, dann sollte ich das eigentlich schon gegeneinander verriegelt haben. :D Wobei ich langsam ein bisschen den Überblick verliere


PS: Ich hab hier mal noch ein paar Screens:

TCP-Verbindung wenn nichts gesendet wird
Unbenannt.jpg

TCP-Verbindung wenn gesendet wird
Unbenannt3.jpg

@Krumnix: Du meinst mit der Sendegröße die der CP schluckt sicher dies hier:
Unbenannt2.png
 
Zuletzt bearbeitet:
Ja, das Häkchen sollte rein, wenn Daten >240 Byte sind. Der FC5 kann trotzdem nur 240 Byte pro Zyklus senden :)

Wie hast du denn die Verbindung projektiert? Könntest du dazu einen Screenshot hochladen?
 
Zurück
Oben