Array füllen

elmoklemme

Level-2
Beiträge
174
Reaktionspunkte
28
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich muss gerade für meine Technikerarbeit eine Lüftungsanlage von S5 auf S7 umrüsten. Jetzt möchte ich für meine neue Visu einige Temperaturwerte aufzeichnen und als Kurve anzeigen lassen. Hab da an ein Fifo gedacht, dass mir die Werte in nem DB abspeichert. Hab mir dann das Beispiel in der FAQ solang durchgelesen bis ich es verstanden hab, ein wenig angepasst und funktioniert tatsächlich. Nun bin ich heut Mittag bei ner anderen Recherche auf einen alten Beitrag von PN_DP gestoßen der sagt, dass mir diese Aktion abartig Zykluszeit frisst ( sind so ca. 1500 Werte). Er hat das wohl irgendwie mit dem SFC20 BLKMOV gemacht, leider hab ich das nicht verstanden. Außerdem stand noch etwas drin in welcher Reihenfolge die Werte für WinCC flex im DB abgelegt werden müssen. Da bin ich mir jetzt auch nicht mehr sicher was hinten und was vorne sein soll. Wär super wenn mich jemand auf den nächsten Schritt stoßen würd.
 
Nun bin ich heut Mittag bei ner anderen Recherche auf einen alten Beitrag von PN_DP gestoßen der sagt, dass mir diese Aktion abartig Zykluszeit frisst ( sind so ca. 1500 Werte). Er hat das wohl irgendwie mit dem SFC20 BLKMOV gemacht, leider hab ich das nicht verstanden.
Ja, wenn du z.B. in jedem Zyklus solche Anzahl Werte verschieben musst, hat er sicherlich Recht.
Darum muss man dann schauen ob es nicht Sinnvoll wäre sich den Wert für den Zeiger zu merken und den neuen Wert in dem DB hinten einzureihen.
Kommt halt immer auf die Fakten an.
 
Also ich hab an sich keine Vorgabe, das wird halt ein Gimmick weil mich das ganze interessiert. Fünf Temperaturen werden erfasst und ich dachte für mich dass alle 5 min ein Wert abgespeichert wird und eben für jede Temp die letzten 24 Stunden gespeichert werden. Wären also 1440 Real Werte. Wir haben eine 315er CPU drin und das restliche Programm ist jetzt nicht der Hammer. Also Die Zykluszeit würde vielleicht schon im Rahmen bleiben. Mich würd halt interessieren wie man sowas vernünftig/besser machen kann.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Fünf Temperaturen werden erfasst und ich dachte für mich dass alle 5 min ein Wert abgespeichert wird und eben für jede Temp die letzten 24 Stunden gespeichert werden. Wären also 1440 Real Werte. Wir haben eine 315er CPU drin und das restliche Programm ist jetzt nicht der Hammer.
Also da hätte ich jetzt überhaupt keine bedenken.
Und der SFC20 ist schon gut.
Mich würd halt interessieren wie man sowas vernünftig/besser machen kann.
Was besser machen?
Ich glaube mich an das Thema erinnern zu können.
Da ging es aber um sehr viel mehr Werte und darum hatten PN/DP bedenken.
 
Hallo SPS_LB,

ich denke, für Deine Aufgabe mit 2880 INT-Werten ist ein FIFO nicht gut geeignet.
5758 Byte komplett umspeichern, nur um 2 Byte der Liste hinzuzufügen ... tststs

Hast Du mal im CPU-Baugruppenzustand auf die Zykluszeiten geschaut?

Wenn es schon unbedingt ein FIFO sein muß, dann sollte das Einspeichern in den FIFO wenigstens effizient
programmiert sein.

Das Beispielprogramm von Kai benötigt dafür auf einer aktuellen CPU 315 immerhin 19,3 ms.
Wenn man die unnötigen Berechnungen und das Zwischenspeichern aus der Schleife verbannt, dann läßt
sich die Bearbeitungszeit auf 16,2 ms drücken.
Wenn man immer gleich 2 INT-Werte auf einmal umspeichert, dann braucht man nur noch 8,7 ms.
Und mit Einsatz der SFC20 "BLKMOV" sinkt das Ganze auf 2,7 ms.
(weil SFC20 immer aufsteigend kopiert, ist dann der älteste Wert im FIFO vorn und der neueste hinten)

Also hab grad mal noch nen Ausschnitt rausgesucht. Du hast recht, sind doch ettliche Werte mehr. Wie gesagt ich möcht ja dazulernen, vielleicht hab ich ja mal mehr Werte. Noch setz ich den SFC20 nicht ein, sondern schaufel eins nachdem anderen nach oben, weil ich nicht weiß was er da genau gemacht hat. Der SFC20 kopiert mir ja nur einen Speicherbereich eins zu eins?
 
Jetzt möchte ich für meine neue Visu einige Temperaturwerte aufzeichnen und als Kurve anzeigen lassen. Hab da an ein Fifo gedacht, dass mir die Werte in nem DB abspeichert.
Die Idee ist genau richtig, wenn Du die Werte später als bitgetriggerte Kurven anzeigen willst.
(als FIFO benötigst Du ein REAL-Array je Temperaturwert)

Dann muß aber üblicherweise der älteste Wert am Anfang des Array stehen und der Neueste am Ende.
Jeder neue Wert wird am Ende eingefügt, nachdem zuvor alle anderen Werte im FIFO einen Platz nach vorn
umgespeichert wurden. Der älteste Wert wird dabei vom zweitältesten Wert überschrieben und verschwindet.
Die Kurve in der Visu "rutscht" dadurch um eine Zeiteinheit nach links. Am rechten Ende der Kurve steht
der neueste Meßwert.

Je nach Größe des FIFO und Programmiergeschick kann das Schieben/Umspeichern des FIFO erheblich lange
dauern. Das aufzuzeigen war der Grund meiner damaligen Beiträge. *)

Wenn es schon unbedingt ein Datenspeicher mit der Notwendigkeit des Umspeicherns sein muß, dann sollte
das Umspeichern großer Datenmengen wenigstens effizient programmiert sein.
Zumindest sollte man erkennen, daß man durch solche Umspeicher-Aktionen stark schwankende Zykluszeiten
verursacht, was Probleme bereiten kann, wenn die CPU auch noch Positionier-Aufgaben erfüllen soll.

Wie lange das Umspeichern bei Dir genau dauern wird, hängt stark von der eingesetzten CPU ab. Die neuesten
300-CPU dürften noch um den Faktor 5 schneller sein als meine damaligen Benchmarks mit der CPU 315-2EH13.

Fünf Temperaturen werden erfasst und ich dachte für mich dass alle 5 min ein Wert abgespeichert wird und eben für jede Temp die letzten 24 Stunden gespeichert werden. Wären also 1440 Real Werte. [...]
Mich würd halt interessieren wie man sowas vernünftig/besser machen kann.
Mache für jede Temperatur einen eigenen FIFO (REAL-Array), damit Du für die Visu die einzelnen Temperaturen
nicht erst mühsam aus Datensätzen mit je 5 Werten raussortieren mußt.

Also, wenn Du den SFC20 statt der oft empfohlenen indirekten Umspeicher-Schleifen verwendest, dann habe
ich wie Paule keine Bedenken. Du mußt 5 mal 287 REAL-Werte (5 mal 1148 Byte) umspeichern.

Deshalb würde ich das Einspeichern der 5 Temperaturen in die 5 FIFO auf 5 aufeinanderfolgende OB1-Zyklen
verteilen, wobei ich mir im ersten der 5 Zyklen alle 5 Temperatur-Abtastwerte merke und den ersten Wert
in seinen FIFO einspeichere und dann im 2. bis 5. Zyklus jeweils die im ersten Zyklus gemerkten anderen
Temperaturwerte in ihre FIFO einspeichere.

Denkbar wäre auch, der Visu/Panel das Archivieren der 5 Temperaturen zu überlassen. Das vereinfacht auch
das Anzeigen der Kurven. Allerdings werden dann die Werte nicht aufgezeichnet, wenn die Visu/Panel-Runtime
nicht läuft.

Noch setz ich den SFC20 nicht ein, sondern schaufel eins nachdem anderen nach oben, weil ich nicht weiß was er da genau gemacht hat. Der SFC20 kopiert mir ja nur einen Speicherbereich eins zu eins?
Der "Trick" beim Einsatz des SFC20 besteht darin, daß die Speicherbereiche sich überlappen und die Zieladresse
genau 1 REAL-Wert vor der Quelladresse liegt, so daß genau der zweite bis letzte FIFO-Eintrag auf den ersten bis
vorletzten FIFO-Eintrag umgespeichert wird. Zum Schluß wird der neue Wert auf den letzten FIFO-Wert gespeichert.


*) Hier die Beiträge, auf die sich elmoklemme im Eröffnungspost bezieht:
jede Minute einen Datensatz aufzeichnen mit Programmbeispiel 48-Stunden-Ringpuffer ohne Umspeichern
Benchmark 2879 INT-Werte umspeichern (INT-kopier-Schleife vs. optimierte Schleife vs. SFC20)
Umkopieren 99 Werte mit SFC20 "BLKMOV" Programmbeispiel

Gruß
Harald
 
Der "Trick" beim Einsatz des SFC20 besteht darin, daß die Speicherbereiche sich überlappen und die Zieladresse
genau 1 REAL-Wert vor der Quelladresse liegt, so daß genau der zweite bis letzte FIFO-Eintrag auf den ersten bis
vorletzten FIFO-Eintrag umgespeichert wird. Zum Schluß wird der neue Wert auf den letzten FIFO-Wert gespeichert.

Auszug aus der S7 Hilfe zum SFC 20:

Quell- und Zielfeld dürfen sich nicht überlappen. Ist das angegebene Zielfeld größer als das Quellfeld, dann werden auch nur so viele Daten in das Zielfeld kopiert, wie im Quellfeld stehen.
 
Hab ich auch schon gelesen. Das würde ja heißen ich muss je Temperatur mit zwei verschiedenen DBs arbeiten!? Mittlerweile hab ich das so umgesetzt wie PN/DP geschrieben hat (mit einem DB) und kurz angetestet. Fehlermeldung gabs keine und rein optisch sieht es auch so aus als ob es geht. Hat jemand andere Erfahrungswerte?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
warum 2 DB's?

du verschiebst einfach innerhalb eines DB's um eine Zeile

Also z.B: dein DB 1 hat Array 1..100 of INT

auf die Adresse DB1.DBW0 soll der "neue" Eintrag, dann musst du vorher die Alten Daten um ein INT nach unten verschieben...

also 99 -> 100; 98 -> 99; 97 -> 98 usw.

statt jetzt ne Schleife zu nehmen und das indirekt zu proggen verschiebst du via Blockmove (der Baustein, nicht unser Blockmove :ROFLMAO:) den ganzen DB um eine Zeile. Also wird DB1.DBW0 zu DB1.DBW2; DB1.DBW2 zu DB1.DBW4 usw..
 
Ja so hab ich das auch gemacht (wie von PN/DP beschrieben) und wie gesagt funktioniert es. Es ging ja um die Aussage, dass sich Quell und Zeilbereich nicht überlappen dürfen (was ja der Fall ist wenn ich in einem DB umkopier!?). Ist da jetzt was dran oder kann ich das schnell wieder vergessen?
 
Wenn sich Quelle und Ziel nicht überlappen geht es ja nicht.
Warum das in der Siemens hilfe steht weiß ich auch nich..:confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
so...

Also ich hatt's auch schon mal an einer CPU probiert und da hat es nicht funktioniert! Weiss aber auch nicht mehr was das für eine war!

Ich denke halt wenn man es macht, kann man sich nicht sicher sein, das es mit einer neuen CPU auch noch funktioniert!
 
dann musst du vorher die Alten Daten um ein INT nach unten verschieben...

also 99 -> 100; 98 -> 99; 97 -> 98 usw.

statt jetzt ne Schleife zu nehmen und das indirekt zu proggen verschiebst du via Blockmove [...]
Also wird DB1.DBW0 zu DB1.DBW2; DB1.DBW2 zu DB1.DBW4 usw..
Genau dieses NACH HINTEN verschieben funktioniert NICHT mit dem SFC20 "BLKMOV", deshalb schreibt
wohl Siemens abschreckend, daß sich Quell- und Zielfeld (generell) nicht überlappen dürften.

Da der SFC20 auf allen mir bekannten S7-CPU immer aufsteigend kopiert (steht auch so in der SFC20-
Beschreibung) und ich davon ausgehe, daß er höchstens 32 Bit (= 4 Byte) auf einmal transferiert,
sehe ich keine Probleme darin, den SFC20 auch für überlappende Speicherbereiche einzusetzen, wenn
die Zieladresse mindestens 4 Byte VOR der Quelladresse ist.
(man könnte dazu ja ein schönes Bildchen mit Pfeilen und vorher/nachher malen)
Wahrscheinlich spielt der Abstand gar keine Rolle, hauptsache die Zieladresse ist nicht hinter der
Quelladresse (könnte man ja mal testen).

Jedenfalls funktioniert dieses überlappende nach-Vorn-Kopieren bisher auf allen S7-300/400-CPU, wo
ich es so eingesetzt habe. Der SFC20 führt den überlappenden Kopierauftrag ohne Fehlerstatus aus.
Der SFC20 führt vor dem Kopieren so viele Parameterprüfungen aus, wieso lehnt er das überlappende
Kopieren aber nicht ab?!

Es kann bei neuen CPU oder beim nächsten Firmware-Update natürlich sein, daß das überlappende
Kopieren nicht mehr wie erwartet funktioniert. Siemens hat ja ohne Einschränkung geschrieben:
"Quell- und Zielfeld dürfen sich nicht überlappen".
Das wird man dann aber sehr schnell mitbekommen und muß sich eben was anderes "schnelles" einfallen
lassen. Doch wenn es auf einer CPU einmal funktioniert, dann wird es ohne Firmware-Update auch immer
funktionieren.

Ich könnte mir vorstellen, daß die Längenangabe des Any-Pointers sogar bestimmt, wie der SFC20 kopiert
- P#DB1.DBX0.0 BYTE 12 -> byte-weise
- P#DB1.DBX0.0 WORD 6 -> word-weise
- P#DB1.DBX0.0 DWORD 3 -> doppelword-weise
weiß aber im Moment nicht, wie ich das testen/nachweisen kann.

Im übrigen ist es gerade bei Produkten für Siemens-PLC gang und gäbe, von Siemens nicht dokumentierte
und nicht garantierte Funktionen angstfrei zu nutzen und auch unwissenden Anwendern als "funktionierend"
anzubieten. Außer Chemie-Katastrophen und Tod von Menschen kann ja nichts schlimmeres dabei passieren.

Mein überlappendes Kopieren mit dem SFC20 ist wenigstens von mir getestet und ich gehe davon aus, wer
das nachmacht, wird sich auch mindestens einmal von der korrekten Funktion überzeugen.

Wer sich nun nicht mehr traut, mit dem SFC20 überlappend zu kopieren, der kann ja auch zweimal kopieren,
wie hier von vierlagig vorgeschlagen: http://www.sps-forum.de/showthread.php?p=222991
Das sollte immer noch schneller als eine indirekte Kopierschleife sein.

Gruß
Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist das auch in PLCSim getestet?
Ja, selbstverständlich. Und funktioniert auch korrekt.

Läuft das so auch auf Vipa CPUs?
Habe ich nicht getestet, ich habe erst einmal mit VIPA-CPU gearbeitet.
Ich meine aber, daß das überlappende Kopieren auch da funktionieren wird, wenn der SFC20 auch da immer aufsteigend arbeitet.
Wenn VIPA kompatibel zu Siemens sein will, dann muß es da auch funktionieren.

Was dokumentiert Siemens zum SFC20 "BLKMOV" ?

System- und Standardfunktionen für S7-300/400 Band 1 und Band 2 (05/2010)
Seite 97, Kapitel 3.1 Speicherbereich kopieren mit der SFC 20 "BLKMOV"

3 Aussagen:
  1. Quell- und Zielfeld dürfen sich nicht überlappen. (ohne weitere Erläuterungen oder Einschränkungen)
  2. Das Kopieren erfolgt in Richtung aufsteigender Adressen
  3. Beachten Sie, dass während der Bearbeitung der SFC 20 "BLKMOV" die Quelldaten unverändert bleiben.
    Andernfalls ist die Konsistenz der Zieldaten nicht gewährleistet.

zu 3.) Diese Aussage betrifft eigentlich die Unterbrechbarkeit des SFC20 durch OB. Der Quellbereich wird also nicht
gesperrt oder gesichert. Schreiben in den Quellbereich während der SFC20-Bearbeitung ist eindeutig möglich.

zu 1.) Die erste Aussage halte ich einfach für ungenau. Vielleicht hat der Dokumentationsschreiber einfach keine Lust
gehabt zu beschreiben, unter welchen speziellen Bedingungen diese Aussage gilt und welche Ausnahmen zulässig sind.
Der SFC20 läßt jedenfalls das "verbotene" überlappende Kopieren ohne Fehlerstatus zu und führt es korrekt aus.

zu 2.) Die zweite Aussage dagegen lege ich nun streng aus:
Das Kopieren erfolgt strikt in Richtung aufsteigender Adressen.
Nach dem Kopieren eines Elements egal welcher Zugriffsbreite wird ein Element von einer höheren Adresse kopiert, niemals
ein Element von einer niedrigeren Adresse als ein vorheriger Kopiervorgang. Damit nun garantiert jedes Element immer in
aufsteigender Folge kopiert wird, muß nach dem Kopieren eines Elements genau das nächste Element kopiert werden. Würde
dabei eine Lücke gelassen, müßte irgendwann auch diese Lücke kopiert werden, was aber der Aussage mit der aufsteigenden
Arbeitsweise widerspricht. Wenn ich nun noch unterstelle, daß sinnvollerweise kein Byte zweimal kopiert wird, dann muß
der SFC20 in etwa so arbeiten:

for i=1 to elementanzahl ; ziel = quelle ; i=i+1 ; next

(das kann auch ein einzelner komplexer Prozessorbefehl sein wie REP MOVSB bei 80x86)

Der ganze Vorgang ist so auch logisch und entspricht allen meinen Erfahrungen mit verschiedenen Programmiersprachen und
Prozessoren. Ich kann mir nicht vorstellen, was für einen völlig anderen Algorithmus die CPU-Firmware-Programmierer da
angewendet haben könnten, der überlappende Bereiche tatsächlich generell verbieten würde.

Wenn aber - wie gezeigt - der SFC20 in einer Schleife die einzelnen Elemente eines Quellbereichs in einen Zielbereich
umkopiert (ohne Lücken und ohne mehrfach kopieren), dann finde ich keinen Grund dafür, daß die Bereiche sich nicht
überlappen dürfen, solange die Zieladresse kleiner oder gleich der Quelladresse ist. Es muß ja nur sichergestellt sein,
daß kein Element überschrieben wird, was noch nicht kopiert wurde. Und das ist der Grund, weshalb ein aufsteigendes
Kopieren mit Zieladresse größer Quelladresse ("nach hinten") bei überlappenden Bereichen nicht korrekt funktioniert.
Und wegen dieser speziellen Einschränkung schreibt Siemens halt einfach, daß die Bereiche sich nicht überlappen dürfen...

Interessanterweise erwähnt Siemens bei den vergleichbaren Bereichs-Übertragungsbefehlen der S7-200 (BMB/BMW/BMD/BLKMOVE)
nicht diese speziellen Bedingungen für überlappende Bereiche. Es gibt gar keine Einschränkungen. Jeder Programmierer muß
selbst drauf kommen, was geht und was geht (logischerweise) nicht.

Ich behaupte, daß der SFC20 immer erfolgreich kopiert, wenn diese Bedingungen eingehalten werden:
1. der Zielbereich muß größer oder gleich groß wie der Quellbereich sein
2. und beide Bereiche müssen physikalisch komplett vorhanden und für den SFC20 zulässig sein
und
3a. die Zielbereichsadresse ist kleiner oder gleich Quellbereichsadresse
3b. oder Zielbereichsadresse ist größer Quellbereichs-Endadresse
3c. oder der zielbereich ist ein völlig anderer Speicherbereich als der Quellbereich (anderer DB oder TEMP oder Merker ...)
und
4. spezielle Bedingungen für BOOL und STRING siehe SFC20-Beschreibung

Ich bin sehr zuversichtlich, daß das von mir verwendete überlappende Kopieren mit dem SFC20 auch in Zukunft immer korrekt
funktionieren wird, solange Siemens die Zusage der aufsteigenden Arbeitsweise einhält.

Gruß
Harald
 
Zurück
Oben