TIA KOP+SCL Programmierung - Abspeichern von gemessenem Druck in Speicherfelder unter Bedingung

HT-T

Level-2
Beiträge
118
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich programmiere mein aller erstes Projekt mit einer CPU 1212C AC/DC/RLY nachdem ich vor einiger Zeit einen Grundkurs zur S7 Programmierung abgeschlossen habe. Die im folgenden beschriebene Problemstellung ist der erste Abschnitt meiner Programmierung in welcher ich aktuell leider nicht weiter komme.
Ich würde es begrüßen wenn ihr mir weiterhelfen könntet.

Mein Programm ließt einen Druckmessumformer Analogwert ununterbrochen ein und wandelt diesen in den gewünschten Druckbereich (0-1000mbar) um.
Nun würde ich gerne diese ausgelesenen Druckwerte abspeichern um mit diesen dann anschließend mathematische Ableitungen durchzuführen.
Ich habe bereits einen DB Baustein als mein Storage System erstellt und die entsprechenden Variablen verteilt.

Input Variablen:
-> Put_In - auf diese Variable wird der aktuelle Druckwert übergeben [int]
-> Selected_Shelf - per Default auf 0 gesetzt [int]

->Post_Put_In - soll als Bedingung dienen sodass bei einem gleichbleibenden Druck der Wert nicht weiter in die fortlaufenden Ablageorte kopiert wird.

InOut Variable:
-> Shelf_Outletpressure (Array 0...1000) [int]
-> Reset - setzt alle Shelf Ablageort auf 0 insofern TRUE [Bool]


Der zugehörige FB zu meinem Storage System habe ich im SCL wie folgt gestaltet:

---------------------------------------
//Schleife soll gestartet werden wenn der gemessene Druck größer 0.//
IF #Put_In > 0 THEN
//In das Selected_Shelf, welches per Default auf 0 beim Programmstart gesetzt ist soll der gemessene Druck geschrieben werden. //
#Shelf_Outletpressure[#Selected_Shelf] := #Put_In;

IF #Shelf_Outletpressure[#i] <> #Shelf_Outletpressure [#i + 1] AND #Put_In <> #Post_Put_In THEN
//Um sicherzustellen das durch die kurze Zykluszeit nicht alle Ablageorte des Shelf mit einem gleichbleibenden (da manuell simuliert) Wert beschrieben werden würde ich hierfür gerne eine Bedingung schaffen. Ich vermute dass ich hier zu kompliziert denke aber meine Idee war es einen dem Put_In durch einen Taktgeber nachgestellten "Post_Put_In" abfragen zu können.//

//Der Ablageort soll um eine Stelle nach oben rutschen insofern die zuvor genannten Bedingungen erfüllt sind. Insofern dies geschehen ist soll zur vorherigen Bedingung gesprungen werden und erneut durchlaufen werden. //
"Storage".Selected_Shelf := +1;
RETURN;
END_IF;
END_IF;

// FOR LOOP um alle Ablageort des Shelf nach Betätigung der Bool Variable auf 0 zu setzen.//
IF #Reset = TRUE THEN
FOR #i := 0 TO 1000 DO

"Storage".Shelf_Outletpressure[#i] := 0;
END_FOR;
END_IF;



Leider stehe ich nun vor dem Problem dass ich keinen geeigneten Baustein für die gedachte Abfrage des Post_Put_In finde, vermutlich werde ich das über einen weiteren SCL Baustein probieren solange ich hier auf einen professionellen Rat hoffe.

Ich würde mich freuen von euch zu hören.

Grüße euer HT-T
 
Ich verstehe noch nicht so ganz was du mit #Post_Put_In erreichen möchtest. Du hast doch bereits eine Abfrage drin die verhindert das gleich Werte geschrieben werden.

Allerdings verstehe ich den Schleifen Ansatz nicht. Der Wert Put_In bleibt in der Schleife unverändert, was willst du mit Schleife erreichen?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe auch fast nur Bahnhof. Alles klingt sehr verworren.
Wie hast Du einen DB mit Input- und InOut-Variablen erstellt???
Wie sehen die Deklarationen des "FB" aus?
Wie wird der FB aufgerufen?
Wo kommt der Wert für den Input Selected_Shelf her? Wo und wann wird er weitergestellt?
Was soll dieser Code im FB bewirken: "Storage".Selected_Shelf := +1;
Was soll IF #Shelf_Outletpressure[#i] <> #Shelf_Outletpressure [#i + 1] ... bedeuten? Warum wird da ein Eintrag ( ...[#i] ) mit dem nächsten Eintrag ( ...[#i + 1] ) verglichen?
Wo hast Du Deine "Schleife"? Ich sehe keine.
Warum ist Reset eine InOut Variable?
Sollte Reset nicht Vorrang vor anderen Operationen haben?
...

Kannst Du mal ohne Implementations-Details erklären, was Du machen willst?

Harald
 
Zuletzt bearbeitet:
Die erste Bedingung (#Shelf_Outletpressure[#i] <> #Shelf_Outletpressure [#i + 1]) verhindert eben gerade nicht das der selbe Wert geschrieben wird. Wobei ich auch mit einem Code leben könnte der mir die Felder mit dem selben Wert beschreibt, nur eben nicht so schnell das mein gesamter Speicher aus ein und dem selben Messwert besteht da ich ansonsten nichts mit den Messwerten anfangen kann.

Ja die Schleife ist Mist, ich glaube ich habe noch nicht das Verständnis für eine funktionierende Schleife wie ich sie brauchen würde, bzw. wie ich es mir vorstelle. Ich weiß leider nicht wie ich die Schleife auszuführen habe das er den Wert ließt speichert dann ein Speicherpunkt weiterspringt wieder einließt usw. deshalb suche ich hier auch Hilfe.
 
@PN/DP
@TheQuest : Ich vermute es wäre besser gewesen hier nicht meine ersten kleinen Schritte in der SCL Programmierung vorzuführen da ich diese selbst als sehr mangelhaft einschätze :D.

Ok bevor ich auf all die Fragen eingehe versuche ich erneut mein Ziel zu formulieren, vielleicht können wir dann gemeinsam ein neues Programm erörtern welches mir weiterhilft.

Ich habe einen gemessenen Ausgangsdruck (zwischen 0-1000mbar) diesen simuliere ich, solange das Programm nicht wie gewünscht funktioniert natürlich noch von Hand über die Simulationstabelle.

Ich benötige ein Programm welches automatisiert die gemessenen Werte in einem Speicherort ablegt, einen Speicherort weiter hüpft um hier den nächst gemessenen Wert abspeichert u.s.w. somit habe ich dann nach einer gewissen Zeit eine kleine Datenbank gespeichert mit welcher ich den Druckverlauf graphisch darstellen möchte und anhand eines weiteren Programms anhand des sich veränderten Druckverlaufs verschiedene Rückschlüsse auf das Gesamtsystem schließen (Bsp: Schnell abfallender Druck - Leckage ; Gleichbleibender Druck - Ventil am Ausgang geschlossen etc.

Der erste Schritt wäre also eine Datenbank und ein zugehöriges Programm zu schaffen in welchem ich die Werte einlese und speichere. Für jeden normalen SPS Programmierer wird das wohl kein Akt sein, ich lerne aktuell lediglich durch YouTube Videos Trial-and-Error und Forenbeiträge.

Ich hoffe ich habe euch mit meinem schlampigen Beitrag hier nicht vollends verärgert...

Frage: Soll ich eventuell meinen ersten Eintrag editieren und nur die Fragestellung formulieren anstelle meines sinnlosen Codes? :))

Grüße
HT-T
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Stimmt da habe ich mich verlesen, mit -1 würde es aber klappen. Aber da die Schleife keinen Sinn macht ist es auch egal.

Für mein Verständnis braucht du keine Schleife. Du erfasst den Wert Zyklisch (wobei ich dafür eine seperate Abtastrate in definieren würde)und speicherst ihn, wenn er Ungleich zum letzten Wert (ob das Sinnvoll ist für deine Auswertung sei mal dahin gestellt) ist schreibst du in deinen Speicher, anschließend erhöhst du den Index um 1. Den Index musst du während der ganzen Sache natürlich auf Gültigkeit prüfen.

Wir Harald schon fragte, wer hat "hat der Reset vorrang?"

Mit dem Reset (löschen der Daten) setzt du diesen Index wieder auf 0.
 
@TheQuest

1656427290088.png
Ok, wenn ich keine Schleife benötige dann muss ich den "Selected_Shelf" als von einer Input zu einer InOut-Variable umwandeln, da er mir sonst nach jedem durchlaufenen Zyklus den Selected_Shelf auf 0 zurücksetzt, oder?

Könntest du deine Gedanken mit einem Code-Beispiel verdeutlichen, ich bin mir nicht sicher ob ich verstehe was du meinst.

Ich wollte die Bedingung dass er mir bei einem gleichbleibenden Wert, diesen nicht weiter einspeichert nutzen um festzustellen ob er die Veränderung im Programm überhaupt erkennt. Oder ob meine Zykluszeit viel zu kurz ist sodass eine manuelle Simulation gar keinen Sinn macht.
Wie gesagt ich habe leider keine Erfahrungen in diesem Bereich, vielleicht sind die 1000 Speicherfelder auch zu klein gestapelt und er schreibt mir dieser komplett voll bevor ich manuell einen veränderten Wert simuliert habe.

Natürlich möchte ich die komplette Historie aufzeichnen um damit weiter richtig rechnen zu können...

Ich hoffe ich konnte meine Überlegungen erneut etwas besser verdeutlichen.

Den Reset habe ich nur eingefügt um manuell schnell alle Speicherfelder zu leeren.

Danke für eure Antworten!

Grüße
HT-T
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Welche Voraussetzungen müssen erfüllt sein um einen neuen Wert zu speichern? Eventgetriggert oder Zeitgetriggert? Ich denke pro Zyklus deinen Index zu inkrementieren macht wenig Sinn für so eine Messwerterfassung. Was willst du mit den Messwerten erreichen? Willst du eine Langzeiterfassung/Auswertung mache? Dann bin ich der Meinung gehört das Speicher der Daten nicht in die CPU. Falls du die Möglichkeit hast, kannst du die Messwerte in Wincc auf ein Trending legen und das ganze in einem Langzeitarchiv mitschreiben. Daraus bekommst du eine CSV Datei die man dann auswerten kann.
Gruß Pascal
 
Um zu verhindern, daß der Messwert zyklisch geschrieben wird solltest du am EN (oder im Programm) eine Flanke aus einem Takt anlegen
1656489605598.png
Und es macht keinen Sinn den Wert nur abzuspeichern wenn eine Wertänderung auftritt. Das würde den Kurvenverlauf völlig verfälschen.
 
@TheQuest : Danke für die Mühe, ich dachte für die Logik der Loop benötige ich eine Zuweisung des jeweiligen Felds.
So das die Loop weiß welches Feld ausgewählt und zu befüllen ist. Daher die Variable "Selected_Shelf". Würde das Programm so dann bereits funktionieren, dann baue ich das nämlich mal nach und probiere es auch. Wobei ich es so modifizieren würde wie von @volker vorgeschlagen. Ich denke auch für die finale Ausführung macht es keinen Sinn da ansonsten das Messergebnis verfälscht wird. Wenn ich den Taktmerker auf 1s lege, was schon sehr langsam ist dann reicht das jedenfalls zur manuellen Simulation des Drucks.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe ihn nicht Simuliert aber er sollte so funktionieren. Ist halt sehr rudimentär geschrieben und bietet noch Raum für Verbesserungen und Erweiterungen.

Na die Abtastrate wird durch das System bestimmt.
 
@SPS-Pascal : Hallo Pascal, es sollten Zeitgetriggert funktionieren, daher gefällt mir die Lösung von Volker mit dem Taktmerker. Ich möchte das manuelle auslösen eines SAV (Sicherheitsabsperrventil) innerhalb einer Gasregelstrecke anhand der kurzzeitigen Messwerterfassung dokumentieren und auswerten. So das durch den Verlauf des gemessenen Drucks, welchen ich zunächst feststellen muss und mit einer zu programmierenden Logik verbinden darf. Langfristig würde der Prüfstand ohnehin mit einer SQL-Datenbank kommunizieren müssen um die Werte zu speichern. Das liegt jedoch noch in weiter ferne, das aktuelle Ziel besteht vielmehr darin die Werte aufzuzeichnen, zu speichern, auszuwerten mit einer Berechnung und die damit verbundenen Rückschlüsse zu ziehen und Programmtechnisch auszugeben. Eine WinCC Lizenz habe ich aktuell noch nicht und würde es vorerst auch nicht extern auswerten lassen wollen. Ich hoffe mein Vorhaben erneut etwas mehr und besser verdeutlicht zu haben.
Danke für eure Expertise und Hilfe!!

Grüße HT-T
 
@TheQuest : In Ordnung dann werde ich das so mal probieren.
Du meinst die Abtastrate wird durch die Zykluszeit des gesamten SPS-Programms bzw. Zyklus definiert, richtig?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@volker: Danke für den Rat Volker. Das würde bedeuten ich setzen den Taktmerker an den Eingang des Netwerk 3, wie von TheQuest vorgeschlagen und entferne den Baustein "#WertSpeichern" um eine durchgehende Zeitgetriggerte Messung zu gestalten?
 
@HT-T nein, die Abtastrate wird durch das System bestimmt, heißt wie träge oder schnell kann der sich der Druck ändern, welche Genauigkeit wird verlangt, welche Störgröße soll/muss erkannt werden, gibt es externe Einflüsse, wie schnell kann der Sensor Änderungen erkennen usw.
 
@volker Hallo volker,

ich habe jetzt mal das Programm von @TheQuest und dir wie folgt kombiniert, das "Put_In_Last" Netzwerk habe ich jetzt nicht eingebunden, da es wie besprochen die Aufzeichnung in Summe verfälschen würde.

Kannst du mir noch etwas genauer erläutern welche Klassifizierung die Variablen "Flankenspeicher_Takt_1s", "Flanke_Takt_1s" und "M5.5 Taktmerker 1 Hz = 1s" ich habe mit dieser an von Anweisung noch nicht gearbeitet und verstehe nicht wie diese einzubinden sind.
Danke und Gruß
HT-T
1656936761616.png
 

Anhänge

  • 1656936747247.png
    1656936747247.png
    94,5 KB · Aufrufe: 3
Zuviel Werbung?
-> Hier kostenlos registrieren
@TheQuest Hallo, ich habe jetzt mal das Programm nachgebaut um zu probieren ob es wie gedacht auch funktioniert.
Für den Eingang des "arSpeicher" des FB Bausteins akzeptiert er nicht die Adresse des "arSpeicher" des DB4. Um also
die Werte wie gewünscht abzuspeichern benötige ich einen weiteren DB?
Irgendwie verstehe nicht warum er hier nicht die Array aus dem bereits zugewiesenen DB4 akzeptiert.
Ich habe jetzt zur Abhilfe einen weiteren DB erstellt mit selber Benennung.


1656936971896.png
 
Erstmal musst du die Taktmerkerbyte in den Hardware Eigenschaften aktivieren1656937843946.png

Dann würde ich noch einen Start für deine Messung vorsehen, also in etwa so

1656938099548.png

Und dann brauchst du noch einen Speicher in einem Db, sprich ein Array of Int das die gleiche größe hat wie in deinem Baustein
 
@TheQuest Vielen Dank für die schnelle Antwort! :)

Kurz für mein Verständnis...
Also der Taktmerker taktet in 1s Abständen, der P_TRIG erkennt die Positive Flanke und schaltet auf Durchgang, Wozu benötige ich dann noch die Boolsche Zuweisung "Flanke_Takt_1s" ? Diese wäre nach meinem Verständnis für eine weitere Programmierung relevant in welcher die "Flanke_Takt_1s = TRUE" andere Programmabschnitte automatische z.B. deaktivieren, oder aktivieren würde? Diese wäre aus meinem Verständnis dann auch in die "Output" Kategorie zu klassifizieren, oder?

1656938847048.png


Bei deinem jetztigen Beispiel fehlt diese Zuweisung nämlich auch:

1656939125108.png

Danke und Gruß!
 
Zurück
Oben