# PCWorx - Daten/Variablen wie z. B. Zählerstände auf SPS speichern - Warm-/Kaltstart



## Vaninger (19 November 2012)

Hallo liebes Forum,

ich habe verschiedene Anwendungen, bei denen ich Zähler (Impulse Stromzähler; Laufzeit von diversen Verdichtern, etc.) in meiner SPS auswerte. Hierzu verwende ich den in der Oscat Bibliothek vorhandenen Baustein ONTIME.
Leider gibt es hier das Problem, dass bei Warm-/Kaltstart diese Werte wieder weg sind und somit kein kontinuierliches Zählen/Aufsummieren dieser Werte möglich ist. Nun gäbe es ja die Möglichkeit, die Werte stündlich oder dergleichen auf die Speicherkarte der SPS zu speichern und nach einem Warm-/Kaltstart wieder einzulesen.
Hierzu hatte ich bereits einen Baustein von Marc (auch aus diesem Forum), leider funktioniert dieser nicht bzw. nicht immer.

Hat jemand hierzu eine andere Lösung und könnte mir ein wenig behilflich sein?

Vielen Dank und schöne Grüße
Daniel

Controller: Phoenix ILC 350 PN
Software: PCWorx 6.00


----------



## Mobi (20 November 2012)

Hallo,

und wo sind jetzt die Zähler in dem Projekt???

Also ich habe es bei mir so gelöst. Ich habe einen kleinen FB geschrieben fürs toggeln von Ausgängen, und damit der letzte Zustand vor einem Spannungsausfall immer gespeichert ist, habe ich den Ausgang als Remanent/Retain gemacht. Und das klappt wunderbar. Du musst natürlich aufpassen. Du musst den Baustein so schreiben, dass er auch dann den gespeicherten Wert nach einem Warmstart wieder behält und nicht einfach überschrieben wird. Das war am Anfang mein Fehler. Man bekommt es auch nicht im Debug-Modus mit.


----------



## Oerw (20 November 2012)

Hallo Vaninger

der Ansatz mit deinem Projekt ein BackUp Datei zu schreiben ist okay, wo hast du hier Probleme ? Werden die Daten nicht geschrieben oder nicht zurückgelesen ?

Die Lösung von Mobi funktioniert lediglich bei Warmstart, bei Kaltstart werden auuch die Retain Werte zurückgesetzt

PS: lass das FileOpen Execute solange anstehen bis du es wieder schließen möchtest


----------



## Mobi (20 November 2012)

Das mit dem Kaltstart weiß ich. Aber wann sollte schon ein Kaltstart stattfinden. Außer man macht es über den Kontrolldialog.


----------



## Oerw (20 November 2012)

siehe Fragestellung Warm / Kaltstart


----------



## Vaninger (20 November 2012)

Hallo Mobi, hallo Oerw,

vielen Dank für eure Antworten. Habe den Baustein jetzt nochmals getestet, dieser funktioniert nun doch. Hatte diesen auf einer anderen Steuerung laufen, hier gab es immer irgendwie Probleme. Eventuell waren hier auch meine Datentypen falsch deklariert oder dergleichen. Habe den Baustein jetzt in Verbindung mit dem ONTIME BAustein (hier Laufzeit) von Oscat laufen, erste Tests bei KAlt- sowie Warmstart waren erfolgreich und die vorherigen Daten wurden wieder eingelesen... Habe vorher den Datentyp des Bausteins auf DINT geändert, da der Oscat Baustein dies als VarInOut hat...
Ich mache öfters einen Kaltstart, da ich sehr oft große Änderungen mache und da ein Kaltstart ab und an angebracht ist...

Anbei noch ein Screenshot, wenn irgendjemand noch was wissen will, gerne.

Schöne Grüße
Daniel


----------



## Vaninger (20 November 2012)

*Probleme bei anderem Datentyp*

Hallo Leute,

jetzt habe ich doch nochmal eine Frage zu dem Baustein. Anbei habe ich euch hierzu mal mein Testprojekt angehängt. Folgendes Problem: Ich habe den Baustein in meinem Projekt zweimal drin, einmal in Originalversion, einmal den Datentyp des Buffers geändert/angepasst. Leider speichert nur die Originalversion die Werte auf die SPS, die abgewandelte nicht. Hierzu jemand eine Idee?

Danke und schöne Grüße
Daniel


----------



## Oerw (22 November 2012)

Hi

hast du dir die Errorcode von den File Bausteine angeschaut ?


----------



## Mobi (22 November 2012)

Wieso hast du denn FILE_READ_WRITE kopiert und den neuen FILE_READ_WRITE2 genannt? Wieso nimmst du nicht einfach FILE_READ_WRITE. Oder ist an FILE_READ_WRITE2 irgendwas anders, sodass es mir gerade nicht aufgefallen ist? Das ist doch der Grund warum es Funktionsbausteine gibt. Damit man einmal den Baustein erstellt und man ihn mehrmals verwenden kann. Und pass mal ein bisschen auf deine Variablennamen auf, z.B. heißt das nicht utd sondern udt. Und irgendwie hast du noch keinen Standard drin, bei der Benennung von Variablen. Mal klein, mal groß, mal mit Datentyp-Präfix, mal ohne. Und wieso haben die Dateien keine Endung, z.B. .txt oder .log oder so?


----------



## Mobi (22 November 2012)

Übriegens solltest du xKaltStart und xWarmtStart erst rücksetzen wenn xFileDone UND xFileDone2 True ist. Ansonsten hat der zweite Write-Baustein von dem xKaltStart bzw. xWarmStart nix.


----------



## Vaninger (22 November 2012)

Hallo Leute,

vielen Dank für euere Antworten.

@ oerw:
Habe den Fehlercode beobachtet, hat eigentlich keinen Fehler angezeigt. Hat die Datei auch geschrieben, nur leider die Werte nicht eingelesen oder gespeichert?

@ Mobi:


> Wieso hast du denn FILE_READ_WRITE kopiert und den neuen FILE_READ_WRITE2 genannt?


Ich habe bei dem FILE_READ_WRITE2 einen anderen Datentyp als Buffer verwendet. Siehe hierzu den Datentyp FileTypes2. Ich denke auch, dass dies der Grund für das fehlerhafte Einlesen bzw. Speichen der Datei ist. 



> Und pass mal ein bisschen auf deine Variablennamen auf, z.B. heißt das nicht utd sondern udt



Stimme dir voll und ganz zu, ich war etwas in Eile wegen Championsleague und habe dabei wohl nicht so auf die "Einheitlichkeit" geachtet...



> Übriegens solltest du xKaltStart und xWarmtStart erst rücksetzen wenn  xFileDone UND xFileDone2 True ist. Ansonsten hat der zweite  Write-Baustein von dem xKaltStart bzw. xWarmStart nix.



Wird erledigt, danke für den Hinweis 



> Und wieso haben die Dateien keine Endung, z.B. .txt oder .log oder so?



Hatte bisher nicht gewusst, dass dies unbedingt notwendig ist. Das Beispiel (Baustein), das ich damals erhielt, hatte eben auch keine Endung. Werde jetzt aber mal eine Endung verwenden. 

Vielleicht könntet ihr mir auch einfach eine kleine Frage zu dem Datentyp beantworten. Am Liebsten hätte ich eine Struktur, bei der ich einfach eine Zählernummer angebe und zu dieser dann die Laufzeit und die Starts gespeichert werden. Mein Vorschlag hierzu wäre dieser, stimmt das überhaupt so?


```
TYPE
    ZaehlerData    :
    STRUCT
        laufzeit            :    UDINT;
        starts                :    UDINT;
    END_STRUCT;

    Zae_Data_Arr: ARRAY [0..500] OF ZaehlerData;

END_TYPE
```

Wie müsste ich dann den Aufruf dieses Arrays gestalten, wenn ich für Zähler 1 die Laufzeit möchte? Doch so, oder ist dies so falsch? 


```
Zae_Data_Arr[1].ZaehlerData.laufzeit
```


Danke und schöne Grüße
Daniel


----------



## RrBd (23 November 2012)

Hallo,

eigentlich lautet auf den Punkt gebracht die Frage ja: Wie baue ich einen zuverlässig funktionierenden Betriebsstundenzähler? Bei SAIA SPS muss ich einfach für die Zählerstände feste Registeradressen vorgeben. Deren RAM-Nutzung ist so aufgebaut, dass bestimmte Speicheradressen (R 0 für eine Integerzahl im Register 0) einfach vom Programm aus angesprochen werden können. Da kann ich so viele Programmänderungen machen wie ich will, die Werte in so einem Register werden nur geändert, wenn ich das Programm explizit eine entsprechende Operation mit einem Schreibzugriff auf eben diese Speicherstelle durchführen lasse. Ansonsten wird der Inhalt so eines Speicherplatzes unter keinen Umständen angetastet, ist die einzige Gefahr für diese Werte ein Spannungsausfall bei fehlender Pufferbatterie.

Nach meiner Kenntnis gibt es auf einer ILC 1xx keinen Speicher, der einen RESET übersteht. Auch der interne Flash wird offenbar irgendwie gelöscht, (sonst wäre die IP-Adresse der Station nach einem Reset noch erhalten), also gibt es offenbar keine Möglichkeit?

Gruß

Rainer


----------



## Mobi (23 November 2012)

Die Dateien auf dem FTP bleiben trotzdem erhalten. Aber wieso sollte es im Betrieb einen Reset geben?


----------



## Mobi (23 November 2012)

Vaninger schrieb:


> Vielleicht könntet ihr mir auch einfach eine kleine Frage zu dem Datentyp beantworten. Am Liebsten hätte ich eine Struktur, bei der ich einfach eine Zählernummer angebe und zu dieser dann die Laufzeit und die Starts gespeichert werden. Mein Vorschlag hierzu wäre dieser, stimmt das überhaupt so?
> 
> 
> ```
> ...


Also,

als Datentyp sieht das so aus:

```
TYPE
    udtData :
    STRUCT
        Runtime : UDINT;
        Starts : UDINT;
    END_STRUCT;

    ARRAY_OF_COUNTER_0_499 : ARRAY [0..499] OF udtData;
END_TYPE
```

Wie du drauf zugreifst siehst du im Anhang. Der Datentyp heißt dann ARRAY_OF_COUNTER_0_499. Ich habs mal bis 499 gemacht, dann hast du 500 Elemente.


----------



## RrBd (23 November 2012)

Mobi schrieb:


> Die Dateien auf dem FTP bleiben trotzdem erhalten. Aber wieso sollte es im Betrieb einen Reset geben?



Hallo,

das ist nicht die Frage. Ein Betriebsstundenzählerinhalt muss (wie der Tachostand eines Autos) unter allen Umständen (außer SPS-Ableben) erhalten bleiben, also auch bei Programmänderungen. Dabei wird zwar in der Regel nur ein Kaltstart fällig , aber ein Reset (mit Kugelschreiber-Knopfdruck auf Reset-Knopf vor Spannungs-Zuschaltung, bis LED _FF _und _FR_ im Wechsel blinken) ist durchaus nicht ausgeschlossen. 

Ich weiß nicht recht, was _der FTP_ ist, aber die Daten im _webs_-Ordner sind nach dem Reset einer ILC 130 ETH jedenfalls futsch? Der IE zeigt zwar beim Wieder-Aufsuchen nach einem Reset noch die aufgespielten Dateien an, das scheint mir aber Unfug zu sein, jedenfalls sieht mein Seamonkey da nichts mehr (da weiß ich, wie ich den Browsercache lösche), und die Visualisierung funktioniert auch erst wieder, wenn ich die Dateien erneut mit WebVisit aufgespielt habe. Damit fehlt mir bisher weiterhin eine Lösung, wie die Werte übliche "Alltagsaktivitäten" überstehen.

Im Handbuch OSCAT BASIC:LIBRARY Version 3.33 gibt es zum _ONTIME _eine Tabelle, welche _VAR RETAIN PERSISTENT_  und ähnliche bei welcher Aktion erhalten bleiben, aber ich kann leider die dort verwendeten Begriffe _Reset_, _Reset kalt_, _Reset Ursprung_ etc. nicht recht zuordnen. Vermutlich ist "mein Reset" der "Reset Ursprung", der alle Variablen löscht.

Gruß

Rainer


----------



## Mobi (23 November 2012)

Also laut dem Startpost sieht das mir nicht nach Betriebsstundenzähler aus. Eher dier Erfassung von Werten von Geräten, aber nicht deren Laufzeit.
Und wenn ich bei mir den Reset-Taster betätige (lang und kurz) bleibt alles im FTP trotzdem erhalten. Achja die Visu läuft auch. Und bei einer Programmänderung bleiben die Dateien auch erhalten.


----------



## RrBd (23 November 2012)

Mobi schrieb:


> Also laut dem Startpost sieht das mir nicht nach  Betriebsstundenzähler aus.



Hallo,

 also das Posting 19.11.2012, 12:26 "Laufzeit von diversen Verdichtern" sieht mir schon sehr nach einem Betriebsstundenzähler aus, und Oscat-ONTIME ist genau ein Betriebsstundenzähler. Allerdings ist dort lediglich nach "Kaltstartfestigkeit" gefragt, was schon mal die meisten Probleme abdeckt, die Lösungen aus der Diskussion werde ich in den nächsten Tagen mal ausprobieren. 

Mir geht geht es aber ganz allgemein um die Frage, wie solche *wirklich *Daten dauerhaft abgelegt werden können, und das heißt für mich auch über einen Reset hinaus. Gegenwärtig sehe ich da nur die Möglichkeiten, solche Daten auf einen anderen Netzwerkteilnehmer auszulagern, bei bedarf zurückzulesen (1 Betriebsstunde dazugekommen), zu ändern und dann wieder auszulagern (siehe unten). 



Mobi schrieb:


> Und wenn ich bei mir den Reset-Taster betätige (lang und kurz) bleibt  alles im FTP trotzdem erhalten. Achja die Visu läuft auch. Und bei einer  Programmänderung bleiben die Dateien auch erhalten.


 Das ist kein _Reset _entsprechend meiner Beschreibung, also ist das Ergebnis auch nicht unerwartet.

Grüße

Rainer


----------



## Mobi (23 November 2012)

Jo, ich hatte es vorhin einfach gemacht, wenn sie läuft. Habs jetzt nochmal gemacht mit Spannungszuschaltung. Hab genau das beschriebende Verhalten von dir. Also müsste er die Sachen auf einen externen Server Speichern.

Aber "Impulse Stromzähler" sieht mir nicht nach Betriebsstundenzähler aus, sondern eher kWh-Zähler.


----------



## Vaninger (26 November 2012)

Hallo Leute,

vielen dank für eure Antworten und eure Hilfe.



> also das Posting 19.11.2012, 12:26 "Laufzeit von diversen Verdichtern"  sieht mir schon sehr nach einem Betriebsstundenzähler aus, und  Oscat-ONTIME ist genau ein Betriebsstundenzähler



Wie du schon richtig erkannt hast, möchte ich gerne von diversen Geräten (Verdichter, Ventilatoren, Magnetventile, Pumpen, etc.) die Laufzeit sowie die Starts mittels des Bausteins ONTIME aufnehmen. Verbrauch kann dann ja ganz leicht durch Multiplikation mit der Leistung errechnet werden. Da ich ab und an einen Warmstart bzw. Kaltstart machen muss, sind diese Daten dann natürlich immer weg.

Hierfür würde ich eben einen Baustein verwenden wollen, der mir die Stände in einem bestimmten Abstand speichert, und diese dann nach dem Warm-/ bzw. Kaltstart wieder einliest. Der Baustein FC_Backup funktioniert auf meiner Test SPS, sobald ich diesen aber in die laufende SPS verwende, zeigt er nach jedem Einlesen wieder null an.

Anbei ein paar Screenshots meines Aufbaus...

Kurz noch eine andere Frage. Wie macht ihr das oder habt ihr diesen Anwendungsfall gar nicht? Wäre schön, hier endlich eine funktionierende Lösung zu haben.

In diesem Sinne noch einen schönen Abend.

Daniel


----------



## Oerw (27 November 2012)

Hallo Vaninger


der Weg ist schon richtig, um keine Werte nach einem Kaltstart zu verlieren müssen diese auf der FlashCard gespeichert werden. Dies entspricht etwa einem DB auf einer S7.
Ebenfalls ist das Schreiben und Lesen einer Struktur richtig, da dies den Vorteil bietet schnell schreiben und lesen zu können.

Wenn der Baustein auf deiner TestSPS läuft und in der realen nicht, gehe ich hier von einem Unterschied aus. Dieser Unterschied kann in der Hardware oder Software liegen.
Welche SPS Typ ist die TestSPS und welcher Typ die reale ? 
Hast du in deinem Baustein ein Fehlerhandling eingebaut, wo du sehen kannst, ob der Baustein fehlerhaft durchlaufen wurde ?
Kann es sein, das die Größe des Buffers anders ist als in deiner TestSPS ? 
Es sind zwei verschiedene runtime system bei PxC, hier unterscheiden sich auch der Speicherverbruach einer Struktur.
Wird die Datei erzeugt ? Prüfen mit einem ftp client

Um die Größe einer Struktur/Array zu erhalten gehe ich wie folgt vor:

- Erzeuge die Variable mit dem Strukturtyp
- Projekt neu erzeugen
- notiere der Speicherverbrauch, steht unter Info
- Erzeuge eine weitere Variable mit dem gleichen Strukturtyp
- Projekt neu erzeugen
- nehme den aktuellen Speicherverbrauch und subtrahiere den vorherigen 
- die Differenz gibst die als Größe des Buffers zum Schreiben bzwl. Lesen an
- die zweite Variable löschen
- Projekt neu erzeugen


----------



## Vaninger (28 November 2012)

Hallo Oerw,

vielen Dank für deine Hilfe.
Kurz die Beantwortung deiner Fragen:



> Welche SPS Typ ist die TestSPS und welcher Typ die reale ?


Es sind beide ILC 350 PN, somit gleich. Allerdings habe ich auf der Test SPS einen neuere Firmware. Werde versuchen, die andere auch zu aktualisieren.



> Hast du in deinem Baustein ein Fehlerhandling eingebaut, wo du sehen kannst, ob der Baustein fehlerhaft durchlaufen wurde ?


Fehlerhandling ist im Baustein integriert, ist aber nie ein Fehler vorhanden.



> Kann es sein, das die Größe des Buffers anders ist als in deiner TestSPS ?


Dies könnte tatsächlich der Fall sein, hier dürfte hoffentlich der Fehler liegen.



> Wird die Datei erzeugt ? Prüfen mit einem ftp client


Datei wurde erzeugt, allerdings kam ich gestern nicht mehr auf meine Speicherkarte, warum auch immer... Muss ich heute auch mal nachschauen.



> Um die Größe einer Struktur/Array zu erhalten gehe ich wie folgt vor:
> 
> - Erzeuge die Variable mit dem Strukturtyp
> - Projekt neu erzeugen
> - notiere der Speicherverbrauch, steht unter Info



Hier erzeuge ich nur eine Variable mit dem Strukturtyp, keine Array Variable, oder?
Habe derzeit die folgende Struktur erstellt:


```
TYPE     ZaehlerData :     STRUCT         Runtime : UDINT;         Runs    : UDINT;     END_STRUCT;      ARRAY_OF_ZAE_0_499 : ARRAY [0..499] OF ZaehlerData; END_TYPE
```

Somit erzeuge ich eine Variable, die beispielsweise so ausschaut und vom Datentyp ARRAY_OF_ZAE_0_499 ist, oder?


```
Zaehler[1].Runtime
```

Besten Dank für die Antwort
Schöne Grüße
Daniel


----------



## Oerw (28 November 2012)

Entspricht die Dateugröße der erwarteten Größe ?

Um die Speichergröße zu erhalten nehmst du im diesem Fall als Datentyp das array.

Kannst du mir Code posten oder zusenden ?


----------



## Vaninger (28 November 2012)

Hallo Oerw, 
Konnte heute leider noch nichts testen, stelle dir morgen mal ein Beispielprojekt zusammen... 

Schönen Abend noch. 
Grüße 
Daniel 

Gesendet von meinem GT-I9300 mit Tapatalk 2


----------



## Vaninger (29 November 2012)

*Beispielprojekt*

Hallo Oerw,

anbei das funktionierende Beispielprojekt von meiner Test-SPS. Die Bausteine sind genau die gleichen wie auf meiner "Arbeits"-SPS, auch der Datentyp ist gleich.
Wie du siehst, hab ich einmal den Originalbaustein mit dem Datentyp udtFileData verwendet und einmal den abgewandelten ARRAY_OF_ZAE_0_499, beide funktionieren auf der Test SPS. Allerdings sind auf der Arbeits SPS insgesamt deutlich mehr Variablen und Bausteine verwendet, sollte ja hier egal sein.
Habe jetzt auch schon ein Firmware Update auf die aktuelle Version gemacht, funktioniert leider noch immer nicht, wieso auch immer...

Vielleicht hast du ja noch eine Idee.

Schöne Grüße

Daniel


----------



## Vaninger (30 November 2012)

Hallo Oerw,

hab die Speichergröße jetzt mal gemessen, müsste 4000 sein. Somit ändere ich jetzt den Wert bei File_read_cnt und file_write_count auf UDINT#4000, oder?

Danke und schöne Grüße
Daniel


----------



## Oerw (1 Dezember 2012)

Ja

wenn du mehr angibst werden die Funktionen nicht ausgeführt


----------

