e!Cockpit Trace einer Analogvariablen, mehr als 2000 Sampels

Matt87

Level-2
Beiträge
42
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich würde gerne mit der Trace Funktion in e!Cockpit eine Analogvariable über einen Zeitraum von mehr als 2000 Samples mit Loggen.
Ziel ist, ein Druckabfall an einer Druckpistole soll Prozesssicher 50 mal erkannt werden. Die Steuerung schafft das natürlich ohne Probleme im Programm.
Aber ich muss es leider beweisen.
Ein Drucksensor überwacht den Druckabfall und ist an einer Analogkarte angeschlossen.
Die wiederum Samplet mit 50 Hz wenn ich mich nicht täusche? Also 20 ms.
Der Druckabfall besteht für etwa 300-500 ms. Der Peak ist ca. Delta 0,6 Bar.
Ich schaffe es einfach nicht in der Trace Datei genügend Ausschläge Prozesssicher aufzuzeichnen. Ziel wären 3 SPS Zyklen.

Aber das andere Problem ist, dass die Aufzeichnung nur 2000 Samples maximal kann und ich kann sie nirgendwo verlängern.
Kennt jemand eine Methode für mein Problem?
Auf welche Zykluszeit sollte ich die CPU stellen 10 oder 20 ms?

Danke
 
Moin, Trace funktioniert in e!C genauso schlecht, wie in der nativen CS3. Meine persönliche Meinung: Spar Dir Zeit und Nerven und lass es. Schreib die Werte in ein Array und stell die in einem XY-Diagramm dar und zur Beweisführung schreibst Du das Array in eine CSV. Wenn Du Dich beim CSV an das Format vom Datalogger-FB hällst, kannst Du es auch nachträglich mit dem Dataplotter gut Visualisieren. Den Datalogger-FB selbst kannst Du allerdings nicht verwenden, weil der Werte einzeln in CSVs schreibt und daher auf max. 1 Sekunde begrenzt ist. Aber Werte eines Arrays mit den File-Write Basis-FB in eine CSV zu schreiben, ist kein Hexenwerk.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok, schade. Also die 2000 Samples lassen sich nicht verlängern?

Muss zugeben so ein Riesen Array hab ich noch nie geschrieben. Wo ist da die Grenze?
Die CSV schreiben am besten mit der Lib von Wago?
Danke
 
Eine harte Grenze durch den Compiler gibt es meines Wissens nicht und der Speicher kann 2000+ Arrays.
Für die CSV würde ich die WagoAppFileDir verwenden, da ist ein FB zum Schreiben einer Datei drin (irgendwas mit write file halt). Den verketteten String aus Zeitstempel, Trennzeichen und Wert kannst Du bequem mit den Concat3..9() Funktionen aus der WagoAppString erzeugen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, das ganze Thema ist leider doch nicht so einfach.

Ich habe Probleme beim Erstellen des Arrays.
Wenn ich den FB mit dem Array im PLC_PRG aufrufe, muss ich die IN_OUT Variable mit dem Array beschreiben.
Da ich aber die Länge nicht kenne geht das nicht.

So habe ich das Array deklariert. In der Struct ist ein DINT und ein Real Wert.
VAR_IN_OUT
arValues : ARRAY [*, *] OF stValues;
END_VAR

Ich veruche es so aber das klappt nicht:
FOR diCounter1 := LOWER_BOUND(arValues, 1) TO UPPER_BOUND(arValues, 1) DO
FOR diCounter2 := LOWER_BOUND(arValues, 2) TO UPPER_BOUND(arValues, 2) DO
arValues[diCounter1].diCpu := diCounter1;
arValues[diCounter2].rPe := rP_1;
END_FOR
END_FOR

Es kommt eine Fehlermeldung:
C0126: Variable vom Typ 'POINTER TO stValues' benötigt genau einen IndexPFC200_G2_2ETH_RS_CANFB_TraceZeile 3, Spalte 1 (Impl)06.03.2023 11:06:08


Ich finde im Netz keine richtige Antwort wie ich die Erste und Zweite Dimension des Arrays beschreiben kann.
Also wie rufe ich den FB im PLC_PRG auf und wie beschreibe ich das Array Zyklisch?
Hat jemand eine Idee?


Danke
 
Zuletzt bearbeitet:
Hallo, ich habe es jetzt mit festen Array Grenzen versucht, leider ist jetzt der Speicher voll und ich komme nicht mehr online auf die SPS.

arValues : ARRAY [0..8000, 0..8000] OF stValues;


FOR diCounter1 := LOWER_BOUND(arValues, 1) TO UPPER_BOUND(arValues, 1) DO
FOR diCounter2 := LOWER_BOUND(arValues, 2) TO UPPER_BOUND(arValues, 2) DO
arValues[diCounter1, diCounter2].diCpu := diCounter1 + 1; // Control Counter PLC-Cycle
arValues[diCounter1, diCounter2].rPe := rP_1; //Pressure from Sensor
END_FOR
END_FOR

Das Array wird danach in eine CSV geschrieben, aber zuerst wandle ich das Array in einen WSTRING:

WHILE (arValues[_iwrite,_iwrite].diCpu <> 0) OR (SIZEOF(arValues[_iwrite,_iwrite]) >= _iwrite) DO
wsTxBuffer := DINT_TO_WSTRING(arValues[_iwrite,_iwrite].diCpu);
wsTxBuffer := WCONCAT(wsTxBuffer, STRING_TO_WSTRING (','));
wsTxBuffer := WCONCAT(wsTxBuffer , REAL_TO_WSTRING (arValues[_iwrite,_iwrite].rPe));
wsTxBuffer := WCONCAT(wsTxBuffer , STRING_TO_WSTRING ('$R$N'));
_iwrite := _iwrite + 1;
END_WHILE



Von der SPS erhalte ich folgende Fehlermeldung:
C0106: Kein freier globaler Speicher mehr verfügbar: Variable 'fbTrace', 512130480 Bytes (Größter zusammenhängender freier Speicher 133586836). Inkrementelles Übersetzen oder das Hinzufügen von Variablen zur persistenten Variablenlisten könnte fragmentierten Speicher erzeugen. Führen Sie den Befehl "Liste neu ordnen und Lücken bereinigen" aus um die Liste der persistenten Variablen zu defragmentieren oder "Übersetzen, Bereinigen" um den Speicher für andere Daten und Code neu zuzuteilen.


Hat noch jemand eine Idee was ich tun könnte? Wie komme ich wieder Online auf die Steuerung?
 
Für was brauchst du ein 2-dimensionales Array? 8001*8001 sind 64016001 mal Größe der Struktur. Wäre bei nur einem Byte in der Struktur schon mal 61 Megabyte. Weißt du überhaupt was du tust?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sorry hab sowas seit 5 Jahren nicht mehr gemacht und damals mit TIA.
Hab jetzt die Grenzen fest ohn zweite Dimension aber mit einer Struct.

arValues1 : ARRAY [0..8000] OF stValues;
wsTxBuffer : WSTRING(50000);
wsTxBufferTemp : WSTRING;

So beschreibe ich Zyklisch das Array:
IF diCounter1 < 8000 OR NOT xStart THEN
rP_1Temp := rP_1;
arValues1[diCounter1].diCpu := diCounter1; // Control Counter PLC-Cycle
arValues1[diCounter1].rPe := rP_1Temp;
diCounter1 := diCounter1 + 1;
END_IF

So befüllen ich die WSTRING Variable:

WHILE (arValues1[_iwrite].rPe <> 0) DO
wsTxBufferTemp := DINT_TO_WSTRING(arValues1[_iwrite].diCpu);
wsTxBufferTemp := WCONCAT(wsTxBufferTemp, STRING_TO_WSTRING (','));
wsTxBufferTemp := WCONCAT(wsTxBufferTemp , REAL_TO_WSTRING (arValues1[_iwrite].rPe));
wsTxBufferTemp := WCONCAT(wsTxBufferTemp , STRING_TO_WSTRING ('$R$N'));
wsTxBuffer := WCONCAT(wsTxBuffer, wsTxBufferTemp);
_iwrite := _iwrite + 1;
END_WHILE

Leider weiß ich nicht ob wie groß der String in der WSTRIN Varibale sein darf?
Bekomme einen ERROR dann von der WagoAppFileDir.FbSimpleWriteFile_cpt;

Ein File wird zwar geschrieben, es ist aber leer. Finde in der Lib auch keine Fehlermeldung.

Kann es sein das die Grenzen erreicht sind bei der CSV?
 
Update: Hab das CSV schreiben hinbekommen. Bin von dem WSTRING wieder weg.
Triggere einfach jeden Wert den ich in die CSV schreiben möchte extra. Durch 0D0A weiß der Logger ja das ein neuer Absatz kommt.
Konnte ohne Probleme 10.000 Samples mitschreiben.
Danke
 
Zurück
Oben