TIA Absichern eines NICHT remanenten Wertes (der via S7-Kommunikation empfangen wird)

Mogli

Level-2
Beiträge
132
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen zusammen,

ich stehe hier zur Zeit etwas auf dem Schlauch und brächte Hilfe zu einem Problem.
Wir haben hier 2 SPS die via Profinet miteinander Verbunden sind und kommunizieren.

Die erste SPS sendet einen Gesamtverbrauchswert (Typ REAL) zu der 2. SPS.
Wenn wir hier einen Stromausfall haben, wird der REAL-Wert genullt, da dieser im DB der ersten SPS nicht remanent ist.
Leider haben wir von der ersten SPS kein Programm (bzw. dieses Ist mit Know-How-Schutz versehen).

Die Aufgabe ist es, den empfangenen Wert von SPS 1 in der SPS 2 zu speichern.
Nach einem Stromausfall ist Startet der Empfangene Wert von SPS1 wieder bei 0. Nun müsste man den zuletzt gespeicherten Wert
in SPS 2 mit dem neu empfangenen Wert aus SPS1 addieren.

Aber irgendwie bekomme ich das nicht so ganz hin.
Nachfolgender Programm-Ausschnitt würde ich in SPS2 realisieren.
1642408123635.png

1642407800180.png

Hatte das Testweise mal ausprobiert, jedoch funktioniert es so nicht.

Habt ihr vielleicht eine Idee/ einen Denkanstoß für mich?
Vielen Dank.

Grüße aus Luxembourg
 
Ich würde zuerst eine Speichervariable in der SPS 2 anlegen.
Dann den Eingangswert von SPS 1 auf eine Hilfsvariable umlegen, welche den Wert von SPS1 vom aktuellen Zyklus speichert.

Immer wenn der Eingangswert von SPS 1 auf 0 Fällt, per Flanke, den Wert der Hilfsvariable auf die Speichervariable addieren.

Istwert = Eingangsvariable SPS 1 + Speichervariable SPS 2

Ich hoffe, ich habe deine Thematik richtig verstanden.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

genau das hatte ich versucht zu realisieren.

Ich lesen den Wert aus SPS 1, wenn dieser größer ist als mein Wert in SPS2 dann move ich den aktuellen Wert von SPS 1
in meinen "ersten" TMP_1 Merker in SPS 2.

Sollte der empfangene Wert kleiner sein als der TMP_1 wert, so move ich den empfangenen Wert in meein TMP_2 Merker in
SPS 2. (ignoriere den Merker M200.0, den habe nur zum Testen eingebaut. Der ist "immer" auf "1").

Beispiel:

Der Empfangene Wert ist 100.0, dann Move ich diesen auf "TMP_1". Die Bedingung für den 2.Move Befehl ist nicht gegeben,
somit steht im TMP_2 der Wert "0.0".

Der addierer gibt den Wert 100.0 heraus.

Jetzt empfange ich den Wert 5.0, die Bedingung für den ersten MOVE ist nicht mehr gegeben, die für den 2.Move schon.
Somit wird die Variable TMP_2 auf 5.0 geschrieben.
Der Addierer gibt mir 105.0 raus. Noch ist alles OK.

Jetzt fällt der empfangene Wert auf 0.0, die Bedingung für den ersten Move ist NICHT gegeben (es steht immer noch eine 100.0 in TMP_1),
die Bedingung für den 2. Move ist gegeben, es wird 0.0 in TMP_2 geschrieben.

Am Ausgang des Addierers steht nun 100.0 (Und das ist FALSCH).

Und genau hier habe ich zur Zeit eine Denkblockade.

1642408894058.png
 
Hallo,
ich dachte bei meinem ersten Post eher an so etwas.
Wobei TMP_1 die Hilfsvariable (Receivewert letzter Zyklus) wäre und TMP_2 die Speichervariable.


test.PNG
 

Anhänge

  • test.PNG
    test.PNG
    19,3 KB · Aufrufe: 3
Hi circlehook,

vielen lieben Dank für deine schnelle Antwort.
Dein Beispiel hat mir sehr geholfen!

Grüße aus Lux
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Aufgabe ist es, den empfangenen Wert von SPS 1 in der SPS 2 zu speichern.
Nach einem Stromausfall ist Startet der Empfangene Wert von SPS1 wieder bei 0. Nun müsste man den zuletzt gespeicherten Wert
in SPS 2 mit dem neu empfangenen Wert aus SPS1 addieren.
Das scheint mir ein Widerspruch in sich zu sein.
Solange SPS1 sinnvolle Daten sendet, diese 1:1 in SPS2 abspeichern und sobald SPS1 "spinnt" nur noch den Zuwachs addieren?
Das führt doch dazu, dass wenn SPS1 nicht mehr "spinnt", der durch die "SpinnPhase" verfälschte Wert wieder in SPS2 1:1 übernommen wird.

Du müsstest bei jedem empfangenen Wert die Differenz des aktuellen Wertes zum zuvor empfangenen Wert bilden und die Differenz, sofern sie positiv ist, zum in SPS2 nachgehaltenen Wert addieren.
So sind die Daten in SPS2 zwar nicht wirklich exakt, aber der Schaden, der durch das "Spinnen" von SPS1 ensteht, hält sich in Grenzen.
 
Hallo Heinileini,

Wenn ich das Programm so schreibe wie circlehook es in "Post #4" vorgeschlagen habe, funktioniert es (in der Simulation).

Warum sollten die Werte "Spinnen"?
Das einzige, dass ich noch testweise abgeändert habe, ist der Vergleich vor dem P_Trig:

1642412631791.png

Bislang konnte ich noch nichts finden, das gegen diesen Vorschlag spricht.
Die Änderung habe ich "nur" gemacht, da es vielleicht sein könnte, dass der empfangene Wert (Nach einem Spannungsausfall) vielleicht größer als 0 ist.
 
Warum sollten die Werte "Spinnen"?
Mit "spinnen" habe ich nur versucht, "allgemein" den Fall zu benennen, dass
Nach einem Stromausfall ist Startet der Empfangene Wert von SPS1 wieder bei 0.
Du hast also 2 "BetriebsArten".
1. Der Wert wird von SPS1 1:1 übernommen.
2. Der "unstimmige" Wert wird von SPS1 nicht übernommen. Stattdessen wird versucht "das Beste daraus zu machen".

Wenn nun einmal der Fall 2 eingetreten ist, musst Du fortan dabei bleiben, die ankommenden Daten nach der Methode 2 auszuwerten (bis wann?).
Was machst Du, wenn Du feststellst, dass SPS1 wieder n-mal "ungestörte" Daten entsprechend Fall 1 gesendet hat? Schaltest Du dann automatisch wieder auf BetriebsArt 1 um? Sobald Du das tust, hast Du SPS2 wieder auf den falschen Wert von SPS1 synchronisiert - mit mehr oder weniger Verzögerung.

Mein Vorschlag war deshalb, immer nur in der BetriebsArt 2 zu arbeiten.

Was Du dann aber zusätzlich benötigst (und ich noch nicht erwähnt hatte): eine Möglichkeit, den Wert in SPS2 zu stellen bzw. zu löschen, ganz bewusst "per KnopfDruck".

PS:
Ich sehe das Problem nicht in der programmtechnischen Umsetzung, sondern in der (Un-)Logik, nach der das Programm arbeiten soll.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was Du dann aber zusätzlich benötigst (und ich noch nicht erwähnt hatte): eine Möglichkeit, den Wert in SPS2 zu stellen bzw. zu löschen, ganz bewusst "per KnopfDruck".
Zu "stellen" ist wichtig, denn i.d.R. wird ja der Energieverbrauch durch einen externen Zähler ermittelt, und die SPS bekommt nur Impulse, die sie zählt. Was passiert, wenn die SPS mal steht, aber der Zähler weiter zählt!? Dazu muß dann mehr oder weniger regelmäßig mal der Zähler angepaßt werden.

Ich bin voll bei @Heinileini, nur die Differez des übermittelten Zählers aufzusummieren. Damit hat man eine Funktionsweise, die in jedem Zustand funktioniert.
Beim der Übermittlung einer "nahe Null" Zahl von SPS1 mußt Du aber in Deinem Fall noch zwei Fälle unterscheiden:
  1. Standard-Fall: SPS war aus und fängt wieder von vorne an
  2. Überlauf: SPS1 ist tatsächlich mal so lange gelaufen, daß der Datentyp überläuft.
Beide Fälle mußt Du natürlich unterschiedlich aufsummieren.
 
Hallo Heinileini und JSEngineering,

danke für eure Anmerkungen. Wie würdet ihr dies denn realisieren?

@Heinileini: Das mit der (Un)logik sehe ich genau so. Aber was soll ich tun?
In der SPS 1 wird eine Durchflussmessung gemacht (Gesamtdurchfluss). Jedoch wird der Wert, jedes mal auf "0" geschrieben, wenn die SPS spannungsfrei ist. Die Firma hat diesen Wert NICHT remanent gemacht. Zugriff auf dieses Programm habe ich auch nur "bedingt".

Irgendwie muss ich drum herum arbeiten und den gemessenen/ empfangenen Wert behalten.
Ist nicht besonders schön, aber was soll man machen...
 
Irgendwie muss ich drum herum arbeiten und den gemessenen/ empfangenen Wert behalten.
Ist nicht besonders schön, aber was soll man machen...
Gar nicht (nie!) um den absoluten Wert kümmern, der von SPS1 übermittelt wird!

Immer die Differenz bilden zwischen dem aktuellen Wert von SPS1 und dem vorher zuletzt von der SPS1 gemeldeten Wert bilden.
Wenn die Differenz nicht negativ ist, die Differenz auf den in der SPS2 geführten Wert draufaddieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Gar nicht (nie!) um den absoluten Wert kümmern, der von SPS1 übermittelt wird!

Immer die Differenz bilden zwischen dem aktuellen Wert von SPS1 und dem vorher zuletzt von der SPS1 gemeldeten Wert bilden.
Wenn die Differenz nicht negativ ist, die Differenz auf den in der SPS2 geführten Wert draufaddieren.
Danke für deine Antwort.

Wäre es vielleicht möglich, dass du einen Screenshot deines Vorschlages machen könntest?
Das wäre echt hilfreich.

Schon Mal vielen Dank für deine Mühe.
 
Wäre es vielleicht möglich, dass du einen Screenshot deines Vorschlages machen könntest?
Leider nicht. Ersatzweise in SCL angedacht:
Code:
tdSPS1aktuell := REAL_TO_DINT(irSPS1aktuell) ; // warum REAL?
tdZuwachs := tdSPS1aktuell - sdSPS1zuvor ;
iodZähler := iodZähler + MAX(IN1:=0, IN2:=tdZuwachs) ;
sdSPS1zuvor := tdSPS1aktuell ;
 
Zuletzt bearbeitet:
Leider nicht. Ersatzweise in SCL angedacht:
Code:
tdSPS1aktuell := REAL_TO_INT(irSPS1aktuell) ; // warum REAL?
tdZuwachs := tdSPS1aktuell - sdSPS1zuvor ;
iodZähler := iodZähler + MAX(IN1:=0, IN2:=tdZuwachs) ;
sdSPS1zuvor := tdSPS1aktuell ;
Wir wissen aber nichts über das Sende-Intervall oder wie schnell sich der Durchfluß ändert.
Sofern in tdSPS1aktuell bereits ein Zählwert enthalten ist, unterschlägst Du den.
Es kann ja auch mal sein, daß SPS2 zusammen mit SPS1 abschaltet, aber erst deutlich später wieder startet.

Warum wandelst Du in INT? Ich würde in UDINT wandeln. Kommt natürlich auf die Größenordnung des Durchflusses an, aber damit kann man ggf. auch noch 1..2 Nachkommastellen mitnehmen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wir wissen aber nichts über das Sende-Intervall oder wie schnell sich der Durchfluß ändert.
Sofern in tdSPS1aktuell bereits ein Zählwert enthalten ist, unterschlägst Du den.
Es kann ja auch mal sein, daß SPS2 zusammen mit SPS1 abschaltet, aber erst deutlich später wieder startet.

Warum wandelst Du in INT? Ich würde in UDINT wandeln. Kommt natürlich auf die Größenordnung des Durchflusses an, aber damit kann man ggf. auch noch 1..2 Nachkommastellen mitnehmen.
@Heinileini: Schon Mal vielen Dank für deinen Vorschlag!
Ich bin nicht wirklich vertraut mit SCL, aber wenn ich den Code verstanden habe, dann würde er so in FUP aussehen, oder?

1642425053447.png

Warum möchtet ihr überhaupt wandeln?

Der empfangene Wert ist vom Typ "REAL". angezeigt wird er im HMI als XXXXXX.XX t/h.

@JSEngineering: Wie würdest du das denn sonst realisieren?
Vielleicht kannst du deinen Vorschlag als Screenshot schicken?

Bin mittlerweile recht verunsichert, was nun besser ist.
 
Zuletzt bearbeitet:
Naja, wenn Du das als REAL empfängst, kann man das nicht ändern, Du mußt Dir aber bewußt sein/werden, welche Ungenauigkeiten im REAL stecken. Und da bei einem Gesamtzähler, der lange läuft, nunmal die Zahlen tendenziell groß werden, nimmt die Genauigkeit des REAL immer weiter ab. Dann sind die Nachkommastellen auch Augenwischerei (irgendwann). Da ist man mit Festkommazahlen genauer.

Um mal beim Real zu bleiben:

Code:
trZuwachs := irSPS1aktuell - srSPS1zuvor;

IF trZuwachs < 0 THEN
    iorZaehler := iorZaehler + irSPS1aktuell;
ELSE
    iorZaehler := iorZaehler + trZuwachs;
END_IF

srSPS1zuvor := irSPS1aktuell;
 
Warum wandelst Du in INT? Ich würde in UDINT wandeln. Kommt natürlich auf die Größenordnung des Durchflusses an, aber damit kann man ggf. auch noch 1..2 Nachkommastellen mitnehmen.
Sorry, ich hatte DINT gemeint. UDINT ist natürlich noch "angemessener".
Natürlich kann man n Nachkommastellen berücksichtigen (z.B. RealWert * 1000.) - ich wollte (noch) nicht auf Details eingehen, die noch nicht zur Sprache gekommen sind, sondern lediglich vorschlagen, für die Zählerei (wenigstens) in SPS2 auf Ganzzahlen umzustellen.

Wir wissen aber nichts über das Sende-Intervall oder wie schnell sich der Durchfluß ändert.
Die SendeIntervalle sind relativ irrelevant, solange die zeitlichen Abstände nicht zu gross werden, was immer das heissen mag, auch hier sind uns keine Details bekannt.

Sofern in tdSPS1aktuell bereits ein Zählwert enthalten ist, unterschlägst Du den.
Es wird die Differenz zwischen dem aktuellen und dem Wert "zuvor" gebildet.
War der Wert "zuvor" = 0, so ist die Differenz identisch mit dem evtl. zutreffenden Zählerstand von SPS1.

Es kann ja auch mal sein, daß SPS2 zusammen mit SPS1 abschaltet, aber erst deutlich später wieder startet.
Es wird die Differenz zwischen dem aktuellen und dem Wert "zuvor" gebildet.
War die SPS2 zwischenzeitlich nicht aktiv, so ist der Wert "zuvor" ein länger zurückliegender und die Differenz zwischen dem 1. aktuellen Wert, den die SPS2 nach dem Wiederanlauf registriert und dem vor dem Abschalten von SPS2 zuletzt gelesenen entsprechend grösser.
Sollte SPS1 einen Überlauf haben oder "vortäuschen", während die SPS2 nicht läuft, dann ... keine Ahnung wie man die Daten in einem solchen Fall rekonstruieren soll. Daher mein Vorschlag, eine manuelle Änderung des Zählerstandes in SPS2 einzuplanen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es wird die Differenz zwischen dem aktuellen und dem Wert "zuvor" gebildet.
War der Wert "zuvor" = 0, so ist die Differenz identisch mit dem evtl. zutreffenden Zählerstand von SPS1.
Mein Szenario wäre: Beide SPSen steigen aus (Stromausfall / Hauptschalter beider Anlagen aus / ...). Gespeicherter letzter Wert: 1000 in SPS2.
Jetzt startet die Anlage neu. SPS1 startet (schneller/eher) durch, SPS2 kommt (später, z.B. wegen Fehler oder Netzwerkausfall) dazu und bekommt eine 50 geliefert. Dann würdest Du die 50 unterschlagen, weil neu-alt < 0 wird.
 
Naja, wenn Du das als REAL empfängst, kann man das nicht ändern, Du mußt Dir aber bewußt sein/werden, welche Ungenauigkeiten im REAL stecken. Und da bei einem Gesamtzähler, der lange läuft, nunmal die Zahlen tendenziell groß werden, nimmt die Genauigkeit des REAL immer weiter ab. Dann sind die Nachkommastellen auch Augenwischerei (irgendwann). Da ist man mit Festkommazahlen genauer.

Um mal beim Real zu bleiben:

Code:
trZuwachs := irSPS1aktuell - srSPS1zuvor;

IF trZuwachs < 0 THEN
    iorZaehler := iorZaehler + irSPS1aktuell;
ELSE
    iorZaehler := iorZaehler + trZuwachs;
END_IF

srSPS1zuvor := irSPS1aktuell;
Hallo @JSEngineering,
Vielen lieben Dank für deine Info.

Würden die Probleme, die du in Post#18 beschrieben hast, ebenfalls bei deinem Code hier auftreten?

Ich würde sonst Testweise mal den von dir vorgeschlagenen Code in die SPS laden:

1642427686483.png

Im HMI würde ich dann ggf. einen Button anlegen (mit spezieller Berechtigung), der bei Betätigung dann "0" auf den iorZaehler lädt.

Oder wird dies dann eher nicht benötigt?
 
Post #18 war eigentlich nur für @Heinileini gedacht. Die beschriebene Problematik würde ich über die "if < 0" Bedingung abfangen.

Ich würde den Zähler eher in einem gerechtigungs-geschützten E/A-Feld ausgeben. So daß man beliebige Werte eingeben kann. Weil: Was nützt Dir ein Zurücksetzen auf 0? Wenn, dann mußt Du den Wert korrigieren, indem Du z.B. einen Wert X aufaddierst.

Wo kommt eigentlich der Durchfluß-Wert her? Kann man den Rohwert nicht ggf. in SPS2 direkt verarbeiten? Dann würde sich dieses Problem erledigen...
 
Zurück
Oben