# Messwerte auf interne SD-Karte einer Wago-SPS schreiben im ms-Bereich



## SPS_Jack (24 Oktober 2014)

Hallo zusammen,

ich möchte gerne Messwerte auf eine SD-Karte schreiben, welche in eine Wago-SPS vom Typ 750-880 gesteckt wird. Hierfür verwende ich bereits einen Funktionsblock „FbDatalogger“, welcher aus einer Beispielanwendung stammt, welche auf der Webseite des Herstellers Wago veröffentlicht wurde. Der verwendete Funktionsblock bietet als kleinste (schnellste) Einstellung das Loggen im Sekundentakt an.

Da ich mehr Messwerte pro Sekunde für meine Analysezwecke benötige, wurde die "Beschaltung" des Bausteins von mir derart angepasst, sodass pro Sekunde 5 Messwerte von einer Wago-Leistungsmessklemme vom Typ 750-494 in einem Puffer-Array zwischengespeichert und nach einer Sekunde ausgegeben werden sollen.

Zur Erfassung von 5 Messwerten pro Sekunde ist demnach ein Takt von 200ms notwendig. Dieser wird von einem Pulsgeber aus der OSCAT Standart-Bibliothek mit dem Namen "CLK_PRG" erzeugt. Der Baustein CLK_PRG erzeugt Taktimpulse mit einer programmierbaren Periodendauer. Die Ausgangsimpulse sind jeweils nur einen SPS Zyklus aktiv. 
Hiervon wird die steigende Flanke des Taktes mit dem Standart-Baustein "R_TRIG" erkannt, welcher eine Zählvariable von 1 bis 5 hochzählt (und bei 5 wieder auf 1 zurückgesetzt wird).
Dieses Vorgehen funktioniert soweit auch.

In der auf der SD-Karte geschriebenen csv-Datei ist jedoch in unregelmäßigen Abständen eine Abweichung bei den notierten Zeitpunkten erkennbar. Es wird oft in der geloggten Zeit eine Sekunde übersprungen. Siehe hierzu die angehängte csv-Datei.

Meine Fragen hierzu sind nun:
- Woher kommt diese Zeitverzögerung?
- Gibt es vielleicht eine einfachere Möglichkeit Messwerte von etwa 15 verschiedenen Messgrößen (Strom, Spannung, Wirkleistung,...) mittels eines Programmes auf der internen SD-Karte zu speichern? Im Idealfall wären 10 erfasste Messreihen (Zeilen in einer csv-Datei) pro Sekunde wünschenswert.


Im Anhang habe ich das Problem der csv-Datei als Bild skizziert.
Den Programmausschnitt der Messwerterfassung habe ich als Projektdatei angehangen. (Das "echte" Programm beinhaltet noch andere "Unterprogramme", die andere Funktionen übernehmen.)

Ich hoffe jemand kann mir bei meinen Programm helfen.


Vielen Dank schonmal dafür 



Anhang anzeigen Programmauszug.zip


----------



## weißnix_ (24 Oktober 2014)

OT:
Bin ich ein Dinosaurier, wenn ich sage das es keine gute Idee ist, im Sekundentakt auf eine sd zu schreiben?
Vor allem nicht so kleine Datenblöcke.
Wäre es nicht besser, erstmal einen Block ~4kB zu sammeln und dann zu schreiben?


----------



## weißnix_ (24 Oktober 2014)

Ausser, das ich nicht ganz durchblicke:?
bilde ich mir folgendes ein:
1. Die Flanke auf Dein CLK-Signal ist unnötig, da der Ausgang des CLK-Bausteins nur einen Zyklus lang ist.
2. kann das von Dir gekennzeichnete durch einen kleinen Jitter bei der Programmausführung zustandekommen.
Zwischen 1 und 2 z.B. nur 999ms Abstand
Zwischen 6 und 7 z.B. 1001ms
Logge einfach die Millisekunden mit und dann wird es klarer.

Ich würde sowas direkt von der Systemzeit -hier Sekunde- Triggern lassen und nicht von so einem freilaufenden Generator.


Edit: Falsch-- natürlich von der Millisekunde im Raster 0-200-400-800-0
Und da sieht man es schon. Muss nochmal denken:sm4:


----------



## weißnix_ (24 Oktober 2014)

Du siehst es schon, mit den 200ms bekommst du eine zeitliche verschiebung, weil der neue Messzyklus nach 1200ms erst beginnt.
Oder sollte ich jetzt schlafen gehen???

Unsinn: Schlafen tut not.

0-200-400-*600*-800-...
Das ist der Systemzeitsynchrone Triggerzyklus, und dann klappt es auch mit dem Nachbarn. Dadurch loggst Du immer im gleichen Raster und solltest keinen Jitter im Log mehr haben.

Gute Nacht.

Edit: Nachdem jetzt alle schmerzende Hände vom Schenkelklopfen haben:

Dein Programm in gekürzter Fassung, also ohne die Arrayzuweisungen zum Bleistift, hätte sicher zwischen die Code-Tags gepasst.
Mein Twincat hat jedenfalls mächtig gemeckert beim öffnen.


----------



## SPS_Jack (24 Oktober 2014)

Vielen Dank für die schnelle Antwort. 
Schaue es mir morgen mal an und melde mich dann wieder 
Gute Nacht


----------



## SPS_Jack (25 Oktober 2014)

weißnix_ schrieb:


> 0-200-400-*600*-800-...
> Das ist der Systemzeitsynchrone Triggerzyklus, und dann klappt es auch mit dem Nachbarn. Dadurch loggst Du immer im gleichen Raster und solltest keinen Jitter im Log mehr haben.



Ich entferne also den freilaufenden Pulsgeber aus dem Programm, setze dafür die Systemzeit ein und erzeuge mir Triggerimpulse bei 0ms, 200ms, 400ms, 600ms und 800ms.

Wie kann ich denn die Systemzeit auslesen? Gibt es dafür auch einen Baustein?
Habe in anderen Beiträgen die Bibliotheken SysTaskInfo.lib und SysLibTime.lib mehrmals gelesen.

Sorry, aber bin absoluter Neuling


----------



## weißnix_ (25 Oktober 2014)

Genau. In welcher lib sich bei Wago die Funktionen befinden weiss ich nicht. 


send wia hendi


----------



## weißnix_ (25 Oktober 2014)

Ich halt es so: Fuer Systemspezifisches gibts 'ne Doku

send wia hendi


----------



## SPS_Jack (26 Oktober 2014)

Habe ebend mal ein Test-Programm geschrieben.
Hierzu wird ein Baustein aus der OSCAT-Basis-Bibliothek mit dem Namen RTC_2 verwendet. Der Ausgang XMS gibt die Millisekunden der RTC von 0 bis 999 aus.


Der Eingang SDT bekommt über die Funktion SysRtcGetTime die Zeit des Systems übergeben.


Um die Funktionalität zu überprüfen habe ich eine CASE-Struktur eingefügt, die verschiedene Variablen hochzählen soll, wenn Werte im Takt von XMS auftauchen 0, 200, 400, 600, 800 um die Abfolge zu kontrollieren.


Leider funktioniert dies nicht zuverlässig. Lediglich i, j und m werden nach 2 bis 5 Sekunden (per Zufall?) wie im Bild ersichtlich hochgezählt.


Woran kann das liegen das die Variable XMS nicht sauber von 0 bis 999 hochzählt?


----------



## weißnix_ (26 Oktober 2014)

ms-genaue Erfassung funktioniert nur bei hinreichend kurzen Zykluszeiten.
Für Deine Erfassung solltest Du ein 5ms-Fenster (bzw. auch größer bei längeren Zyklen) zulassen für die Triggerung.
Also nicht Vergleich auf =200ms sonder auf z.B. >=198 AND <= 204.
Dann benötigst Du übrigens wieder den Flankentrigger .


----------



## SPS_Jack (26 Oktober 2014)

Aber wenn ich mir eine 5ms Spanne für die Erkennung des jeweiligen Taktes definiere,  verliere ich dadurch nicht wieder die gewünschte Exaktheit?


----------



## weißnix_ (26 Oktober 2014)

Was ist Exaktheit.
Eine Messung wird nicht genauer, nur weil Du ein digitales Messinstrument verwendest.
Die Genauigkeitsspanne, die benötigt wird, legst Du fest. Und daraus resultiert, was Du Hard- und Softwareseitig vorhalten musst.
Für ms-genaue Abtastung darf Deine Zykluszeit auch nicht länger sein.
Den 5ms-Jitter hast Du jetzt schon, das zeigen Deine Aufzeichnungen.
Das von mir vorgeschlagene Verfahren ist lediglich "optische Aufhübschung" um das Protokoll schön aussehen zu lassen.


----------



## SPS_Jack (26 Oktober 2014)

weißnix_ schrieb:


> Was ist Exaktheit.
> Eine Messung wird nicht genauer, nur weil Du ein digitales Messinstrument verwendest.
> Die Genauigkeitsspanne, die benötigt wird, legst Du fest. Und daraus resultiert, was Du Hard- und Softwareseitig vorhalten musst.
> Für ms-genaue Abtastung darf Deine Zykluszeit auch nicht länger sein.
> ...



Die Messwerte werde ja in einem Puffer-Array gespeichert und wenn der 5. Wert im Array steht wird sofort die Zeile in die csv - Datei geschrieben.

Wenn ich den Pulsgeber entferne, kann ich dann das von mir eben gezeigte Testprogramm so verwenden oder muss ich das verfahren des Loggens noch abändern?


----------



## weißnix_ (26 Oktober 2014)

Was wir hier so angeregt diskutieren, bezieht sich bisher ausschliesslich auf den Pulsgeber.

Dein grundsätzliches Verfahren funzt ja augenscheinlich. Sekündlich kleine Häppchen auf die SD zu schreiben ist glaubensfrage. Ich hatte halt schon etliche defekte (billig) SD's aus Kameras und vor allem Handys, wo zum Leidwesen des Besitzers ausgerechnet der Fotoordner unmöglich ewiederherzustellen war.

send wia hendi


----------



## Chräshe (26 Oktober 2014)

Hallo SPS_Jack,

 wegen dem Trigger:
 Stelle dein SPS-Task von freilaufend auf fest um, wenn du das nicht bereits so hast.  
 Für eine feste Zeiterfassung brauchst du jetzt nur die Anzahl der Zyklen zählen.
 Angenommen die feste Zykluszeit ist 20ms und du willst alle 100ms die Werte erfassen, dann holst du die in jedem 5. Zyklus ab.

 Das wegschreiben in die Datei kannst du dann Triggern, wenn du eine entsprechende Anzahl an Werten „eingesammelt“ hast. Kopiere die dazu deinen umlaufenden Datenpuffer in ein anderes Array, damit die Erfassung im Hintergrund weiterlaufen kann. Die Anzahl zum wegschreiben muss der Größe von deinem Array entsprechen.   
 Auf diese Weise könntest du auch in jedem Zyklus die Werte erfassen, solange bis die SPS von der Zykluszeit nicht mehr hinterher kommt, oder deine Logdatei zu groß wird.

 Was deine Logdaten angeht:
 Übersichtlicher und einfacher zum auswerten ist es, wenn du vorne den Zeitstempel (am besten mit Millisekunden) hast und hinten fortlaufend die Spalten mit den Messwerten. Mehrere Spalten mit dem selben Messwert aber anderer Zeit ist unschön.
 Du kannst normal so viele Werte in eine Zeile Schreiben, bis du an die Grenze mit den 255 Zeichen kommt. Dazu gehören natürlich auch die Steuerzeichen...

 Viel Erfolg
 Chräshe


----------

