TIA Shift von Arraywerten

jro99

Level-2
Beiträge
41
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,
bin relativ neu in der Steuerungstechnik und vorallem in TIA.
Ich stehe vor folgendem Problem. Ich schreibe ein Array von 200 Werten mit einem eigenem Datentypen. Soweit so gut. Diese 200 Werte werden korrekt beschrieben. Nun will ich aber folgendes Erreichen, ich will die neuen Werte immer auf den Ersten Bereich des Arrays schreiben und den vorherigen Wert um 1 nach hinten verschieben. Somit Array[0] auf Array[1] und Array [0] neu beschreiben.

Mir fehlt dazu die nötige Erfahrung, ist das durch ein Schieberegister zu realisieren?

CPU 1500.

Grüße
 
Hallo Zusammen,
bin relativ neu in der Steuerungstechnik und vorallem in TIA.
Ich stehe vor folgendem Problem. Ich schreibe ein Array von 200 Werten mit einem eigenem Datentypen. Soweit so gut. Diese 200 Werte werden korrekt beschrieben. Nun will ich aber folgendes Erreichen, ich will die neuen Werte immer auf den Ersten Bereich des Arrays schreiben und den vorherigen Wert um 1 nach hinten verschieben. Somit Array[0] auf Array[1] und Array [0] neu beschreiben.

Mir fehlt dazu die nötige Erfahrung, ist das durch ein Schieberegister zu realisieren?

CPU 1500.

Grüße
Wie wäre es mit einem FIFO?

Gibts von Siemens auch direkt:
Screenshot 2024-05-29 143048.png

Ansonsten Stichwörter nach denen du suchen kannst: Ringspeicher
 
FIFO ist da vielleicht ein bisschen Overkill.

Array umkopieren zu höherem Index:
Code:
FOR #i := #MAXINDEX - 1 TO 0 BY -1 DO
  MyArray[#i + 1] := MyArray[#i];
END_FOR;

MyArray[0] := #newValue;

Wie groß ist denn der Datentyp? Wieviele Bytes sollen da bewegt werden? Müssen die Einträge wirklich verschoben werden Oder reicht da nicht auch ein Ringpuffer, bei dem wird nur ein Index-Zeiger auf den neuen Puffer-Anfang verschoben anstatt das ganze Array zu verschieben/kopieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Müssen die Einträge wirklich verschoben werden Oder reicht da nicht auch ein Ringpuffer, bei dem wird nur ein Index-Zeiger auf den neuen Puffer-Anfang verschoben anstatt das ganze Array zu verschieben/kopieren.
Das wäre dann genau die Arbeitsweise, die der LGF_FIFO hat ;)
Aber ich stimme dir zu, wenn der Index der Werte im Array nicht funktionsrelevant ist, ist ein Ringpuffer die performantere Lösung.

Indirekte Nachverfolgung von Schüttgut auf einem Förderband wäre beispielsweise so ein indexrelevantes Thema.
 
Oder wenn das Array als Liste auf einem HMI angezeigt wird, dann ist es oft nötig, die Array-Einträge tatsächlich zu verschieben.
Da könnte es auch nötig sein, wie beim Fragesteller den neuen Wert am Anfang des Arrays einzufügen (was für ein effizientes Verschieben der Arrayeinträge als Block ungünstig ist).

Bei Implementation als FIFO müsste der Fragesteller (zunächst den FIFO mit 200 Werten füllen, und danach) vor dem Hinzufügen eines Wertes zunächst den ältesten Wert entfernen. Das ist ein kleines bisschen umständlicher als mit einem festen Array zu arbeiten.
 
Oder wenn das Array als Liste auf einem HMI angezeigt wird, dann ist es oft nötig, die Array-Einträge tatsächlich zu verschieben.
+1
Die Visualisierung von was passiert, oder was das Programm 'denkt' was passiert ist viellicht wichtiger als die CPU Performance.
Habe ein Prozess wo ich zuerst eine Ringpuffer programmiert habe, aber spähter in eine Schieberegister umgewandelt habe, genau um eine Visualisierung machen zu können.

Und heute ist das Thema Programme so 'effizient' wie möglich zu programmieren ziemlich irrelevant.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen Dank für die vielen Antworten. Hilft mir auch weiter das Thema weiterhin zu verstehen!
Datentypen sind REAL & INT.
Ziel soll sein, 200 Werte (1 DB) die von einem Sensor ausgelesen werden + z.B. Nummer der Messung, Betriebsart des Sensors abzuspeichern. Dies funktioniert auch.
Diese Werte sollen dann jeweils immer in ein Archiv-Array (2 DB) mit 200 Werten abgespeichert werden, wenn eine Bedingung (noch offen) erfüllt ist.
Bedingung könnt wahrscheinlich ein Signal (BOOL) --> zum Test oder bei erreichen der 200 Werten im 1 DB sein.
 
Bleibt noch offen: Warum willst du die neuen Werte der neuen Messung am Anfang des Arrays einfügen? Warum nicht am Ende oder als Ringpuffer (immer den ältesten Eintrag überschreiben)?
 
Damit der aktuelle Wert immer der aktuellste Wert der Messung ist. Eventuell verstehe ich auch den Ringpuffer nicht direkt.
Wenn der Ringpuffer voll ist, wird der letzte Wert immer "rausgekegelt" und der aktuellste Wert steht an Stelle 1 ... wenn ich mich nicht täusche
Bin noch am Hilfe lesen und Youtube suchen, wie ich die Werte des vollen Ringpuffers nicht verliere.
Besteht beim Ringpuffer die Möglichkeit den gesamten Puffer zu nehmen und die Werte zu verschieben oder müssen die jeweiligen Daten einzeln verschoben werden?
Noch eine Frage Ringpuffer = FIFO?
Vielen Dank!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Damit der aktuelle Wert immer der aktuellste Wert der Messung ist.
???

Wenn die Messung immer mit dem selben Speicherplatz arbeiten soll, kein Problem: Die Messung hat irgendwo einen Speicherplatz für den Datensatz, und wenn die Messung beendet ist, dann wird der Datensatz in die Pufferspeicherstruktur kopiert (Array , Stapelspeicher oder Ringspeicher). Am besten, man deklariert die Struktur eines Datensatz als UDT, dann braucht man nicht mehrmals detailliert deklarieren.

Besteht beim Ringpuffer die Möglichkeit den gesamten Puffer zu nehmen und die Werte zu verschieben oder müssen die jeweiligen Daten einzeln verschoben werden?
Beim Ringpuffer werden die Einträge nicht verschoben, sondern es gibt nur 1, 2 oder 3 Verwaltungs-Zeiger, die auf das erste und das letzte Element zeigen. Dadurch müssen die Werte in dem Puffer nicht verschoben werden, sondern nur die Zeiger "rücken weiter".

Noch eine Frage Ringpuffer = FIFO?
FIFO = first In, first Out. Ein Rinpuffer ist ein FIFO, die Einträge werden in der Reihenfolge ausgelesen, wie sie eingespeichert wurden. Einspeichern am Ende (dabei wenn bereits voll den ältesten Eintrag überschreiben), Entnehmen vom Anfang.
 
Zuletzt bearbeitet:
Noch eine Frage Ringpuffer = FIFO?
Jein.
Fifo heißt erst einmal "first in, first out", also das erste eingegebene Element wird auch als erstes ausgegeben.
Es gibt prinzipiell zwei Varianten, wie du diese Funktion aufziehen kannst.
Dies beziehen sich darauf wie du die Daten in das Array einsortierst.

Ein Schieberegister wäre das einfachste.
Bei jeder Eingabe schiebst du das komplette Array um einen index nach "hinten" und fügst das neue Element an erster Stelle ein.
Vorteil: der Array-Index entspricht der Reihenfolge in dem die Elemente eingegeben wurden.
Nachteil: Du musst jedesmal das komplette Array "in die Hand nehmen" => braucht viel Performance, speziell wenn die Elemente oder Arrays größer werden.

Ein Ringpuffer ist die "intelligentere" Lösung.
Da merkst du dir über zwei zusätzliche Index-Variablen wo im Array das Erste und wo das letzte/nächste Freie Element liegt.
Der Baustein "LGF_FIFO" aus der Siemens LGF-Bibliothek wäre ein klassisches Beispiel dafür.
Vorteil: bei jeder Ein/Ausgabe muss nur jeweils das betreffende Element verarbeitet werden => minimierter Performance-Verbrauch und unabhängig von der Array-Größe.
Nachteil: die Sortierung der Elemente im Array entspricht nicht der Reihenfolge in dem diese eingefügt wurden. => für Anzeigen als Liste am HMI musst du erst nochmal im Bezug auf die internen Indizes umsortieren.

edit: Rechtschreibung schwer (°ー°〃)
 
Zuletzt bearbeitet:
Danke PN/DP
Hätte gedacht, die Werte verschieben sich durchgehend. Jetzt verstehe ich den Ringpuffer besser!
Aber ich sehe dann richtig, wenn ich die Daten aus dem Puffer abspeichern will, die einzelnen Daten immer iwie abspeichern muss und nicht den gesamten Puffer auf einmal abspeichern kann?
Danke!
 
Ein Ringpuffer ist die "intelligentere" Lösung.
Da merkst du dir über zwei zusätzliche Index-Variablen wo im Array das Erste und wo das letzte/nächste Freie Element liegt.
Der Baustein "LGF_FIFO" aus der Siemens LGF-Bibliothek wäre ein klassisches Beispiel dafür.
Vorteil: bei jeder Ein/Ausgabe muss nur jeweils das betreffende Element verarbeitet werden => minimierter Performance-Verbrauch und unabhängig von der Array-Größe.
Nachteil: die Sortierung der Elemente im Array entspricht nicht der Reihenfolge in dem diese eingefügt wurden. => für Anzeigen als Liste am HMI musst du erst nochmal im Bezug auf die internen Indizes umsortieren.
Das bedeutet, wenn ich schnelle Messungen im ms-Bereich als Daten bekomme vom Sensor wäre das die Performantere Lösung diesbezüglich? Durch den mitgezählten und gespeicherten Nummernfortschritt der Messungen (Messung-NR wird bei jeder Messung um 1 erhöht) kann diesbezüglich der Nachteil ausgeglichen werden oder?
 
Moin jro99,

was meinst Du mit
wenn ich die Daten aus dem Puffer abspeichern will,


die einzelnen Daten immer iwie abspeichern muss
Dabei geht es um die Funktionalität des Puffers und darum, wie Daten ein- und ausgetragen werden.


und nicht den gesamten Puffer auf einmal abspeichern kann?
Der Puffer ist üblicherweise ein globaler DB. Da kannst Du nach belieben drauf zugreifen (auch komplett umkopieren), aber wozu?


Durch den mitgezählten und gespeicherten Nummernfortschritt der Messungen (Messung-NR wird bei jeder Messung um 1 erhöht) kann diesbezüglich der Nachteil ausgeglichen werden oder?
Welchen Nachteil meinst du?


VG
MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
kann diesbezüglich der Nachteil ausgeglichen werden oder?
Mit "Nachteil" meint @Botimperator, dass beim Ringpuffer der aktuelle historisch/logisch erste Eintrag nicht am "physikalischen"/adresstechnischen Anfang des Arrays liegt, sondern irgendwo im Array, auf den der Anfangszeiger zeigt. Will man den gesamten Puffer irgendwo in der historischen Reihenfolge ausgeben (erster/ältester Eintrag zuerst), dann muss man den Array-Inhalt umkopieren. Aber nur dann. Man muss nicht bei jedem Hinzufügen eines Eintrags das ganze Array umkopieren. Dadurch ist der Aufwand für das Hinzufügen eines Eintrags unabhängig von der Arraygröße.

Je nachdem, wie lange die älteren Datensätze im Array erhalten bleiben sollen, kann man auch z.B. bei Beginn eines Messzyklus den Puffer leeren (den Füllzeiger auf den Array-Anfang setzen) und muss dann auch bei einem normalen Array nicht umkopieren, wenn immer am Ende hinzugefügt wird (bis es voll ist). Bei einem Ringpuffer wird bei "voll" einfach der älteste Eintrag überschrieben (und Anfangszeiger und Füllzeiger verschoben) - dadurch wandert allerdings der historische Anfang und das Ende der Einträge durch das Array.
 
Zuletzt bearbeitet:
Es könnte doch auch die dequeue Funktion genutzt werden um alle Werte sauber rauszukicken und dann in ein historisches Array umzuladen, solange bis der Fifo einfach leer ist.
 
Alles klar, ja hatte einen Denkfehler danke für das Aufklären! Verstehe jetzt den "Nachteil".
Entschuldigt die vielen Fragen und Unklarheiten bei mir.

Danke an alle!
 
Zuletzt bearbeitet:
Zurück
Oben