# statische und temporäre Lokalvariblen



## Wolflesch (24 Februar 2008)

Hallo, ich habe schon 3 SPS Bücher durchgearbeitet (Vogel Fachbücher),
aber nie wurde wirklich genau erklärt was der unterschied zwischen einer
temporären und statischen Lokalvariablen ist. Oder was überhaubt der Vorteil eines FB's gegenüber eines FC's ist.
Wenn mir da jemand helfen könnte wäre ich sehr dankbar.


----------



## Ralle (24 Februar 2008)

Sieh mal hier: 
http://www.sps-forum.de/showthread.php?t=5384&highlight=Unterschied+FB

Immer zuerst im Forum die Suchfunktion nutzen.  

Ansonsten nochmal ganz kurz, Statische Variable werden in Instanz-DB des FB abgelegt und sind immer gültig. Im prinzip, kann man auf sie auch aus anderen Bausteinen heraus zugegriffen werden (über den Instanz-DB, auch wenn das von den meisten Programmierern zu Recht als unsauberer Programmierstil angesehen wird). Bis zum ersten Beschreiben haben sie ihren Defaultwert aus dem DB, danach den Wert, mit welchem sie beschrieben wurden. Temporäre Variablen sind nur innerhalb ihres FB/FC gültig und zwar von dem Moment an, wo sie einen Wert zugewiesen bekommen, bis zum Ende des FB/FC. Im nächsten SPS-Zyklus können sie einen völlig unbestimmten Wert haben! Daher eignen sich Temp. Variablen z.Bsp. um Zwischenergebnisse von Berechnungen zu speichern, welche innerhalb eines FB/FC und innerhalb eines Zyklus abgeschlossen werden. Temp. Variablen werden auf dem Lokaldaten-Stack abgelegt, diesen benutzen alle Bausteine.


----------



## Wolflesch (25 Februar 2008)

*temporäre und statische Lokalvariablen*

Danke für die schnelle Antwort, ich hätte noch eine Frage, verliert dann ein RS-Speicher als temporäre Variable nach jedem Zyklus auch seinen Wert.


----------



## Kai (25 Februar 2008)

Ja, der RS-Speicher verliert als TEMP-Variable nach jedem Zyklus seinen Wert. Daher muss man bei einem RS-Speicher immer mit einer STAT-Variablen arbeiten.

Gruß Kai


----------



## Zottel (25 Februar 2008)

Kai schrieb:


> Ja, der RS-Speicher verliert als TEMP-Variable nach jedem Zyklus seinen Wert...
> 
> Gruß Kai


Auch in dem anderen Thread wird gesagt: Nach jedem Zyklus. Das ist NICHT richtig. Der Wert ist nur während eines einzigen Aufrufs GÜLTIG. Das bedeutet, bei mehreren Aufrufen desselben Bausteins in demselben Zyklus ist der Wert ebenfalls nicht mehr GÜLTIG!
Ferner "finde" ich den Ausdruck "verlieren" hier unglücklich: Der Bereich der Lokalvariablen wird möglicherweise überschrieben, möglicherweise auch nicht, das hängt von der Position im Stack und der Stacktiefe nachfolgender Bausteine ab. Auch hat ein überschriebenes Bit mit 50% Wahrscheinlichkeit immer noch denselben Wert...


----------



## Question_mark (25 Februar 2008)

*Ersatz für randomize*

Hallo Zottel,

treffender hätte man es nicht beschreiben können ...

*ACK* 

Aber durch die unsachgemässe Verwendung von temporären Variablen kann man dann eben ganz leicht die Funktion "Randomize" ersetzen ..  :s22:

Gruß

Question_mark


----------



## Onkel Dagobert (25 Februar 2008)

Zottel schrieb:


> ..Der Bereich der Lokalvariablen wird möglicherweise überschrieben, möglicherweise auch nicht..


Man muss also davon ausgehen dass der Wert *verloren* geht! Ich finde den Begriff sehr passend!


Gruß, Onkel


----------



## Zottel (26 Februar 2008)

Onkel Dagobert schrieb:


> Man muss also davon ausgehen dass der Wert *verloren* geht! Ich finde den Begriff sehr passend!
> Gruß, Onkel


Ich finde ihn deshalb unpassend, weil es für jemand, der die Sache nicht verstanden hat, naheliegend wäre, es einfach zu probieren. Dann hat er bei einer Bit-Variablen eine Chance von mehr als 50% (50%, daß die Variable mit demselben Wert überschrieben wird plus die Hälfte der Wahrscheinlichkeit, daß sie in seiner speziellen Konstellation garnicht überschrieben wird), daß er den selben Wert vorfindet. Da mochte er denken: Juchhu, der Wert ist nicht verloren, da ist er ja noch!
Alltagslogik: Was noch da ist, ist nicht verloren.
Aber er ist nicht mehr gültig, soll heißen, (ausschließlich) durch die beabsichtigte Programmlogik bestimmt.


----------



## Wolflesch (27 Februar 2008)

Hallo, in dem SPS Buch Aufbaukurs (Vogelverlag) werden aber temporäre Variablen als Hilfsmerker verwendet (RS-Operation). Und es funktioniert.
Ist da irgendetwas besonderes mit den HM.


----------



## marlob (27 Februar 2008)

Wolflesch schrieb:


> Hallo, in dem SPS Buch Aufbaukurs (Vogelverlag) werden aber temporäre Variablen als Hilfsmerker verwendet (RS-Operation). Und es funktioniert.
> Ist da irgendetwas besonderes mit den HM.


Setz doch mal ein Beispiel rein, wo das vorkommt.


----------



## Wolflesch (27 Februar 2008)

Das ist ein ziemlich langes Programm (Ablaufsteuerung)
Es werden dem Ablauf nach die Hilfsmerker gesezt und wieder zurückgesetz.
(15 Stück alle temporär).


----------



## Zottel (27 Februar 2008)

Wolflesch schrieb:


> Das ist ein ziemlich langes Programm (Ablaufsteuerung)
> Es werden dem Ablauf nach die Hilfsmerker gesezt und wieder zurückgesetz.
> (15 Stück alle temporär).


Entweder wird der gespeicherte Wert verwendet. Dann ist es FALSCH, obwohl es funktionieren KANN, solange kein weiterer Baustein Lokalvariablen nutzt.

Oder der gespeicherte Wert wird niemals verwendet, sondern innerhalb des Bausteins auf jeden Fall überschrieben, wie im folgenden Beispiel:

```
U E 0.0
U E 0.1
S L 0.0
UN E0.0
ON E0.1
R L 0.0
```
Das würde funktionieren, ist aber sehr schlechter Code da

```
U E 0.0
U E 0.1
= L 0.0
```
dasselbe bewirkt.

Wenn ich mich nicht sehr irre, gibt es keine weitere Möglichkeit, wie dieses Programm aussehen könnte. Daher vermute ich daß es ein einfach Beispiel dafür ist, daß man Blödsinn auch drucken und gedruckt verkaufen kann.

Der Verzicht auf R und S-Anweisungen auf Lokalvariablen ist aber auch keine Garantie für den richtigen Umgang mit Lokalvariablen. Der folgende Code speichert auch einen Zustand und ist daher FALSCH:

```
U E 0.0  // Starttaster
O L0.0   // Selbsthaltung
UN E 0.1 // Stoptaster
= L 0.0  // ein
```


----------



## Ludewig (27 Februar 2008)

@ zottel
Bitte _Lokalvariablen_ in _*temporäre *(Lokal-)variablen _ändern. Statische oder IEC-Lokalvariablen können schließlich durchaus speichern.


----------



## Zottel (27 Februar 2008)

Ludewig schrieb:


> @ zottel
> Bitte _Lokalvariablen_ in _*temporäre *(Lokal-)variablen _ändern. Statische oder IEC-Lokalvariablen können schließlich durchaus speichern.


Ja, natürlich!


----------



## Wolflesch (28 Februar 2008)

Ja, in dem Programm wird nur der FB aufgerufen.Ich wollte noch fragen wie groß der Lokaldatenspeicher ist und ob man die Adresse frei wählen kann z.B. L20.0.
Gehe ich recht von der Annahme aus, das der FB nur parametisiert einen Vorteil gegenüber dem FC hat, sonst kann man ja einfach Merker verwenden.


----------



## Zottel (29 Februar 2008)

Wolflesch schrieb:


> Ja, in dem Programm wird nur der FB aufgerufen.Ich wollte noch fragen wie groß der Lokaldatenspeicher ist


Ziemlich groß, gemessen in Bits. Bin nicht sicher, aber ich habe so 2kB im Kopf..


> ...und ob man die Adresse frei wählen kann z.B. L20.0.


Ja, kann man. Aber dabei gibt es die Gefahr, daß es mit automatisch erzeugten Lokalvariablen kollidiert. Die Parameter an einen FC werden über den Lokaldatenstack übergeben. Die Definition von Temp-Variablen benutzt ihn ebenfalls. Wenn keine starken Argumente dagegen sprechen, sollte man TEMP-Variablen reservieren. Vorteil: step7 paßt ihre Lage an, wenn man Parameter oder weitere TEMP-Variablen einfügt.


> Gehe ich recht von der Annahme aus, das der FB nur parametisiert einen Vorteil gegenüber dem FC hat, sonst kann man ja einfach Merker verwenden.


Man kann einfach Merker verwenden. Man hat das zu S5-Zeiten immer getan. Vorteil von FB und Instanzdatenbaustein:
- Du entwirfst eine Baustein zur Motorsteuerung. Der muß irgendwas über Aufrufgrenzen hinweg speichern.
- Du hast mehr als einen gleichartigen Motor, den du mit diesem Baustein steuern willst.
- Nun kannst du einen Instanz-DB pro Motor erzeugen und der speichert die jeweiligen Dinge für Motor 1,2,3..

Zu S5-Zeiten wäre das nicht gegangen, du hättest es so machen müssen:
- Du gibst alle Merker einzeln als Parameter beim Bausteinaufruf an. Die entsprechenden Befehle zum Zugriff auf Parameter sind auf der S5 erheblich langsamer und du hast bei jedem Aufruf eine eventuell lange Parameterliste.
- Du machst Kopien von dem Baustein und paßt die Merker mit der Hand an.
- Du kopierst aus einem DB auf die immer gleichen Merker, rufst den Baustein auf und kopierst alles zurück. Ziemlich viel Code und Handarbeit.
- Du öffnest einen DB vor dem Aufruf und arbeitest im Baustein mit Bits aus dem DB statt Merkern. Das kommt dem Instanz-DB ziemlich nahe. Nachteil: Du kannst im Baustein keine weiteren DBs benutzen, sonst kannst du nicht zurück zum Daten-DB, denn du hast keine Information, welcher DB offen war.
- Du gibst dem Baustein die DB-Nummer als Parameter mit. Das ist ziemlich genau das, was beim Instanz-DB auch passiert. Allerdings bist du selbst dafür verantwortlich, daß der DB die passende Größe und Struktur hat. Darum kümmert sich Step7 beim Erstellen.

Temporäre Lokalvariablen haben noch einen anderen Zweck: Sie sind nützlich, wenn du innerhalb eines Bausteins Zwischenergebnisse bilden wilst. Bei Bit-Logik ist das manchmal nützlich, um die Programmlänge zu verkürzen und oft, um das Verständnis zu erleichtern:

```
U E0.0  // Sicherheitslichtvorhang frei
U E0.1 // Tuer zu
U E0.2 // Schleuse zu
= #Sicherheit gegeben // Zwischenergebnis in Lokalvariable
```
Danach können alle Ausgänge mit "Sicherheit gegeben" und-verknüpft werden.
Noch drastischer nützen Lokalvariablen bei Rechnungen, z.B. Analogwertverarbeitung:

```
L PEW 0 // Potistellung
ITD
DTR
L 26748.0
/R
L 100.0
*R
T #Potistellung  //Potistellung in Prozent
L PEW 2 // Drehzahl
... // verschiedene Rechenschritte
T #Drehzahl  //Drehzahl in UpM

L #Potistellung
L #Drehzahl
*R
T #DrehzahlAbhängigerAntrieb //Drehzahl in UpM
... // verschiedene Rechenschritte
T PAW0 // Ausgabe an Antrieb
```
Hier dienen die Zwischeergebnisse dazu, den Programmablauf zu strukturieren und sie ermöglichen es, die Werte in technischen Einheiten zu beobachten (Prozent, UpM). Ferner muß, wenn z.B. ein anderer Drehzahlgeber eingesetzt wird, nur der Teil bis zur Errechnung der UpM angepaßt werden.
In beiden Beispielen haben die Zwischenergebnisse #Sicherheit gegeben bzw. #Potistellung und #Drehzahl nur während der Ausführung des Bausteins Bedeutung.


----------



## AUDSUPERUSER (29 Februar 2008)

Hallo Zottel

Ziemlich groß, gemessen in Bits. Bin nicht sicher, aber ich habe so 2kB im Kopf..

Ich hatte bei den (zumindest alten) 300 CPUs den Wert 128kB für den Lokaldatenspeicher im Kopf. Bei den 400 CPUs war das doch einstellbar.

Liege ich hier falsch, oder habe ich die Frage falsch verstanden? 

Gruss

Audsuperuser


----------



## Ralle (29 Februar 2008)

Also die 318 hat 4096 Byte lokaldaten, die werden aufgeteilt auf verscheidene Prioritätsklassen. Standard ist 256 Byte je Klasse. D.h., ein Baustein hat 256 Byte zur Verfügung. Bei Stringverarbeitung sind die ganz fix aufgebraucht :twisted:, zwei lange Strings geht schon nicht. Die anderen 300-er haben etwas weniger, wieviel weiß ich aber nicht exakt (2k könnte hinkommen), aber 256 Byte je Prioritätsklasse bleibt wohl, ist dort auch nicht einstellbar und taucht daher gar nicht erst in den CPU-Einstellungen auf.


----------

