Das einzige Problem was ich jetzt noch habe ist, das beim eimaligen Aktualisieren der 8*4000 Werte für ca 30 Sekunden eine Kommunikationswarnung zwischen Steuerung und TP generiert wird.
Ohh, Du hast noch ein - womöglich sogar größeres - Problem:
In der ganzen langen Zeit, während Dein Lesen-und-Speichern-Script läuft (Schleife!), werden keine weiteren Scripte ausgeführt. WinCC flexible kann nur 1 Script "gleichzeitig".
Die Frage die ich mir nun stelle ist, ob man das aktualisieren dieser 8* 4000 externen Variablen(die in mehreren Arrays abelegt sind) irgendwie besser koordinieren könnte.
Dazu müsste ich aber erstmal wissen wie man das automatische einmalige Aktualisieren der Variablen beim Öffenen des Bildes(auf dem sich der Button befindent der das Skript auslöst) unterbindet.
Das automatische Aktualisieren aller Variablen, deren Verwendung im Bild WinCC flexible bekannt ist, kann man meines Wissens nicht unterdrücken. Selbst Variablen, die nur geschrieben werden sollen, werden von WinCC flex beim Bildaufbau gelesen. Auch eine Einstellung "Lesen nur auf Anforderung" hilft nicht.
Es ist klar, daß Deine tausenden Variablen nur zum Zweck des Exports einmalig konsistent gelesen werden sollen und deshalb jedes zyklische Lesen sinnlos ist. Genau dafür gibt es die "Rezepturen", die nur ein anderer Name für "Datensatz" sind. Rezepturen kann man sehr schön konsistent ins Panel einlesen und muß sich um die Aktualisierungsart und -rate überhaupt keine Gedanken machen (Systemfunktion GetDataRecordTagsFromPLC). Dein Problem mit dem Aktualisieren der 8 * 4000 Variablen gibt es dann gar nicht. Außerdem spart so eine Rezeptur in Deinem Projekt wohl auch ungemein Powertags.
Deine vielen Variablen werden doch wohl irgendwie wiederkehrend strukturiert sein oder sich strukturieren lassen - am besten als ARRAY[..] OF STRUCT, notfalls als ARRAY[..] OF BYTE oder ARRAY[..] OF DWORD. Dann betrachte das ganze als "ARRAY OF Datensatz" und bilde die Struktur eines Datensatzes in einer Rezeptur ab. Da man die Adressen einer Rezeptur in WinCC flex nicht dynamisch ändern kann, müßte Deine CPU etwas mithelfen und den jeweils zu lesenden Datensatz in die als Rezeptur parametrierten Adressen kopieren, die dann als Lesepuffer dienen. Dies wäre am einfachsten eine einzelne Struktur mit dem selben Aufbau wie das ARRAY[..] OF STRUCT. Die Rezeptur wäre dann auf genau diese einzelne Struktur anzulegen.
Ich hatte mal mit einem MP370 320 Datensätze je 220 Byte ~ 70kByte aus einer 315-2 PN/DP in eine csv-Datei zu exportieren.
Das Panel war per Ethernet mit der SPS verbunden.
Damit das Script zum Datensatz lesen und exportieren in die csv-Datei nicht die ganze Zeit die Scriptbearbeitung des Panels blockiert, habe ich das Script in 3 Scripte aufgeteilt und diese dann ereignisgesteuert aufgerufen.
Damit das schneller ging, hatte ich zum Auslesen je 4 Datensätze zu insgesamt 80 Datensatzblöcken je 880 Byte zusammengefasst.
Wenn ich mich richtig erinnere, hat das ganze knapp 3 Minuten gedauert. Die Aktualisierungsrate der 2 Event-Variablen war wohl auf 500ms eingestellt. Während der Lesezeit habe ich am Panel einen Fortschrittsbalken angezeigt, damit der Operator den ordnungsgemäßen Fortgang sieht.
Vereinfacht dargestellt lief das so ab (DS = Datensatz):
Code:
[SIZE="1"]. . Panel . . . . . . . . . . . . . . . SPS . . . . . . . . . . . . . . . . . . . . .
(1) Vorbereitungen, Header schreiben
[COLOR="Blue"]DS_Nummer_REQ[/COLOR] := 1 ---> [COLOR="blue"]DS_Nummer_REQ[/COLOR] <> [COLOR="blue"]DS_Nummer_ACK[/COLOR] ? <-------------+
Exit | |
v |
kopiert gewünschte(n) DS in Rezeptur-Buffer |
[COLOR="blue"]DS_Nummer_ACK[/COLOR] Event "Änderung" <--- [COLOR="blue"]DS_Nummer_ACK[/COLOR] := [COLOR="blue"]DS_Nummer_REQ[/COLOR] |
| |
v |
(2) [COLOR="blue"]DS_Nummer_ACK[/COLOR] = [COLOR="blue"]DS_Nummer_REQ[/COLOR] ? |
[COLOR="DarkRed"]GetDataRecordTagsFromPLC[/COLOR] - DS wird aus Rezeptur-Buffer gelesen |
Exit / |
+--- fertig ---- <- |
| |
+--> [COLOR="Blue"]rdStat[/COLOR] := 4 ---> [COLOR="blue"]rdStat[/COLOR] (kann als Quit Lesen ausgewertet werden) |
| |
[COLOR="blue"]rdStat[/COLOR] Event "Änderung" <--- --/ |
| |
v |
(3) [COLOR="blue"]rdStat[/COLOR] = 4 ? |
Export DS in csv-Datei |
[COLOR="blue"]DS_Nummer_REQ[/COLOR] < letzte ? |
INC [COLOR="blue"]DS_Nummer_REQ[/COLOR] ---> -------------------------------------------------+
Exit[/SIZE]
DS_Nummer_REQ, DS_Nummer_ACK und rdStat sind INT- oder WORD-Variablen in der SPS.
rdStat wird bei GetDataRecordTagsFromPLC als Statusvariable angegeben und signalisiert das Ende des Einlesens.
(x): Script (1), Script (2) und Script (3)
Script (1) wird vom Operator per Schaltfläche aufgerufen, prüft ob schon ein Export-Job läuft, erstellt die csv-Datei und fordert den ersten Datensatz an.
Script (2) wird aufgerufen, wenn die SPS das Bereitstellen des gewünschten Datensatzes im Rezepturpuffer in DS_Nummer_ACK signalisiert und startet das Einlesen des Datensatzes (der Rezeptur) aus dem Rezepturpuffer in das Panel (GetDataRecordTagsFromPLC).
Script (3) wird aufgerufen, wenn das Einlesen des Datensatzes in das Panel beendet ist (mit rdStat = 4 signalisiert), exportiert den Datensatz in die csv-Datei und fordert das Bereitstellen des nächsten Datensatzes im Rezepturpuffer der SPS an.
Die 3 Scipte können für besseres späteres Verstehen auch zu 1 Script zusammengefasst werden, dann muß der Script-Aufrufer dem Script einen Parameter mitgeben, wer der Aufrufer ist und am Anfang des Scriptes ist ein Sprungverteiler oder das Script ist in 3 Abschnitte eingeteilt, welche abhängig von der Caller-Nummer im Aufrufparameter bearbeitet werden.
Alle Variablen-Schreib- und -Lese-Vorgänge werden vom Panel ausgeführt (die SPS ist nur Server), deshalb ist die Dauer des Datenlesens fast nur von der Aktualisierungsrate der Event-Variablen abhängig, aber fast nicht von der Anzahl Variablen je Datensatz.
(genau genommen darf außerdem nicht schneller gelesen werden, als auf die MemoryCard geschrieben werden kann - dürfte aber bei den heutigen schnellen SD-Cards nicht vorkommen)
Beim Export jedes Datensatzes in (3) wird die Datei geöffnet und geschrieben und geschlossen.
Harald