Zur Sicherheit mal die Nachfrage, ob Deine Gerätschaften aktuell sind. Was benutzt Du?
- CPU 315: 6ES7315-.......... Firmware V.....
- CP343-1: 6GK7343-.......... Firmware V.....
- FC6 AG_RECV ist V4.7?
- FC5 AG_SEND ist V4.2?
Der Fehler 80B1 kommt imho von der SFC59 RD_REC und tritt da angeblich nur bei alten CP auf.
(Oder vielleicht auch bei Firmware-Problemen oder Inkompatibilitäten?)
Es ist bei CP343-1 definitiv möglich mit mehreren verschiedenen verriegelten AG_RECV-Aufrufen zu arbeiten (z.B. zur Erhöhung der Verständlichkeit des Programms), ich verstehe allerdings nicht, wieso Du da so große Probleme mit hast. Doch wenn Du das nicht in den Griff bekommst - die gute Nachricht: es geht auch mit nur 1 AG_RECV "für alles".
Eigentlich ist es gar nicht nötig, das Antwort-Telegramm vom PAC zu zerstückeln und abwechselnd über verschiedene AG_RECV-Aufrufe zu empfangen. Die Länge der PAC-Antwort ist nicht wirklich dynamisch variabel, sondern steuerbar/bekannt. Man muß nur geschickt dafür sorgen, daß alle 3 Antworten gleich lang sind und schon reicht 1 AG_RECV mit nur 1 konstantem RECV-Buffer-ANY für alles.
Bei solchen Kommunikations-Aufgaben nehme ich mir üblicherweise zuerst ein Blatt Papier und einen Stift und entwerfe die Lösung, statt per trial-and-error loszuprogrammieren.
Zuerst: Warum liest Du eigentlich die Register bis 302 vom PAC3200? Brauchst Du die wirklich? Was erwartest Du in den Registern 223 bis 302? Ist das irgendwo dokumentiert, ob und was da drin steht? Die fertigen Siemens-Bausteine lesen diese Register nicht.
Um das Ausleseprogramm zu vereinfachen und ohne Schrittkette auszukommen, würde ich wohl folgendermaßen vorgehen:
- bei PAC3200 nur die Register 1 bis 222 lesen
- bei PAC4200 zusätzlich die Register 223 bis 370 lesen (falls tatsächlich Bedarf)
Dies läßt sich in genau 3 bzw 5 Anforderungen von jeweils 74 Registern aufteilen, wodurch das RX-Telegramm vom PAC immer 9 + 148 = 157 Byte lang ist --> es kann für alle Anfragen mit nur 1 AG_RECV gearbeitet werden.
- in die PAC-Abfragen einen Identifizerungs-Code im Header-Transaction-Identifier einbauen, den der PAC zurückgibt, dann kann man die AG_SEND und AG_RECV völlig unabhängig voneinander programmieren. Man kann alleine am TI im RX-Telegramm-Header erkennen was es enthält:
Code:
Transaction Identifier TI Empfangsdaten Payload --> speichern in DB83
----------------------------------------------------------------------------
1 = Register 1 - 74 RECV-Buffer Byte 9 .. 156 DBB0 - DBB147
2 = Register 75 - 148 RECV-Buffer Byte 9 .. 156 DBB148 - DBB295
3 = Register 149 - 222 RECV-Buffer Byte 9 .. 156 DBB296 - DBB443
4 = Register 223 - 296 RECV-Buffer Byte 9 .. 156 DBB444 - DBB591
5 = Register 297 - 370 RECV-Buffer Byte 9 .. 156 DBB592 - DBB739
Dies kann einfach in AWL mit direkter Angabe der absoluten Adressen runterprogrammiert werden (ähnlich dem Programm von kassla #24).
Wenn man will kann man es mit etwas mehr Aufwand auch symbolisch lösen, wobei da das größte Problem ist, daß in S7 Structs nicht auf ungeraden Adressen anfangen können. Ich würde da vermutlich mit ANY-Pointern arbeiten, welche ich zunächst symbolisch entgegennehmen würde und dann um 1 Byte kürzer (für AG_RECV) oder 1 Byte früher (für BLKMOV) manipuliert in ANY-Variablen speichern würde.
- alle 9 Bytes im RX-Header auf Korrektheit prüfen, insbesondere die Längenangaben im Byte 5 und Byte 8
Wenn nicht korrekt, dann RX-Telegramm verwerfen, wenn mehrere aufeinanderfolgende RX-Telegramme Fehler haben (z.B. durch Verschiebungen im RECV-Buffer oder Fehlermeldung des PAC), dann mit FC10 AG_CNTRL CMD 2 CN_RESET die Verbindung beenden und neu aufbauen lassen.
Ich habe leider keine PAC zum testen zur Verfügung (wir benutzen Janitza UMG96RM), sonst hätte ich statt vieler Worte lieber das Programm zusammengetippt. Doch vielleicht finde ich noch Zeit dazu..
Harald