Array für Histogramm

McNugget

Level-1
Beiträge
220
Reaktionspunkte
10
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo allerseits.

Ich möchte ein Array mit Realwerten erstellen um diese in einem Histogramm darzustellen.

Leider bin ich bisher kläglich gescheitert, wenn es darum ging, Arrays und "Schiebefunktionen" im Strukturierten Text zu definieren.

Ich möchte ein Array mit 240 Elementen haben. Diese sollen im x-Minuten-Takt (definierbar) geschrieben und weitergeschoben werden.


Wie müsste ich so etwas im strukturierten Text definieren?

Muss ich für das Histogramm in das letzte Element des Arrays schreiben und "hoch-schieben"? Oder anders herum?

Vielen Dank schon mal an: "wer immer sich erbarmt".

;-)

Gruss

McNugget
 
Hallo,
das ist zwar SCL-Code ... sollte aber im Wesentlichen für die zu gebrauchen sein :
Code:
FUNCTION_BLOCK FB100              
 
VAR_INPUT
   neue_Daten : REAL ; 
   Takt_vor    : BOOL ;        // Schiebe-Speicher vor-takten
END_VAR

VAR
   Daten_Speicher : ARRAY [1..240] OF REAL ;
   FM_Takt : BOOL ;   
END_VAR
VAR_TEMP
   i  : INT ; // Schleifen-Variable
END_VAR
 
BEGIN
 
IF Takt_vor AND NOT FM_Takt THEN 
   FOR i := 239 TO 1 BY -1 DO
       Daten_Speicher [i +1] := Daten_Speicher [i]  ;
   END_FOR ;
   Daten_Speicher [1] := neue_Daten  ;
END_IF ;
FM_Takt := Takt_vor ;
 
END_FUNCTION_BLOCK
Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nicht Schieben ...

In der Regel macht man ein Array mit fester Länge und einen Schreib/Lese "Zeiger". Die Zeiger am Ende angelangt machen einen Wrap (Überlauf auf 0) . Das Rumkopieren kostet zuviel Zeit.
 
:confused::confused::confused: kommt immer darauf an, was man mit den Daten so vor hat. Ich sehe da nicht Schlimmes daran und der Zykluszeitbedarf für diese Verschiebe-Aktion, die alle paar hundert (oder tausend) Zyklen mal stattfindet hält sich sogar bei Siemens noch in Grenzen ...

Gruß
LL
 
Topic schrieb:
Array für Histogramm

Das Histogramm ist eine art Kurve die das Array visualisiert. Ob man hier schiebt oder nicht ist keine Frage der Zykluszeit sondern des Geschmacks. Bei den Histogrammen bevorzuge ich das Schieben der Werte. Bei anderen Anwendungen (FIFO und Co) vermeide ich das.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Falls du schon Arrays für Histogramme schieben musst, dann dürfte Memcpy performanter sein als Schleife, was vor allem bei nicht sehr rechenstarken Plattformen wichtig ist:

IF Takt_vor AND NOT FM_Takt THEN
MEMCPY(ADR(Daten_Speicher[2]), ADR(Daten_Speicher[1]), SIZEOF(Daten_Speicher) - SIZEOF(Daten_Speicher[1]));
Daten_Speicher[1] := neue_Daten ;
END_IF ;
FM_Takt := Takt_vor ;

Gruß,
witkatz
 
Danke Euch allen.

Super, wenn so etwas eine Diskussion auslöst, da kann man sehr gut mit lesen und die Gedankenansätze lernen.

Also entweder Performance, oder eben Idiotensicherheit für mich.. ;-)

@Larry Laffer: Wie muss ich es schreiben, wenn ich das Histogramm nicht von links nach rechts sondern von rechts nach links beschreiben möchte?

@Witkatz: Was genau macht die Funktion Memcpy und in welcher Bibliothe finde ich die??


Gruss und guten Appetit

McNugget
 
Zuviel Werbung?
-> Hier kostenlos registrieren
die Schleife umgekehrt wäre dann so :
Code:
IF Takt_vor AND NOT FM_Takt THEN 
   FOR i := 2 TO 240 BY 1 DO
       Daten_Speicher [i -1] := Daten_Speicher [i]  ;
   END_FOR ;
   Daten_Speicher [240] := neue_Daten  ;
END_IF ;
FM_Takt := Takt_vor ;
den Memcopy (bzw. dessen Syntax) kenne ich leider nicht - der sollte das aber auch können ... wahrscheinlich ungefähr so :
Code:
IF Takt_vor AND NOT FM_Takt THEN
   MEMCPY(ADR(Daten_Speicher[1]), ADR(Daten_Speicher[2]), SIZEOF(Daten_Speicher) - SIZEOF(Daten_Speicher[1]));
   Daten_Speicher[240] := neue_Daten ;
END_IF ;
FM_Takt := Takt_vor ;
Gruß
LL
 
@witkatz: Das hatte ich natürlich nicht gesagt: Ich verwende Wago 750-841 mit Codesys 2.3 und der OSCAT.Lib V3.10.

@Larry Laffer: Vielen Dank. Werde gleich mal ein wenig damit spielen.



Wie kann ich diese Schleifen sicherer lernen? Gibt es ein howto für Dummies????


Gruss

McNugget
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@zotos: Recht hast Du.. hab´s gefunden. Ich hatte gar nicht erst geschaut, da ich annahm, dass es sich um eine ausschliessliche Beckhoff-Funktion handeln würden. Danke.

Wenn ich dieses Array jetzt etwas aufpusten möchte, also 20 Real-Werte zum gleichen Zeitpunkt schreiben möchte. Wie erweitere ich es um diese Dimension? (Ist Dimension richtig?)

Die Ausgabe müsste dann ungefähr so lauten :
Daten_Speicher[1]= 1.11; 2.22; 3.33;...; 22.22;
Daten_Speicher[1]= 1.11; 2.22; 3.33;...; 22.22;

(Habe da mal Beispielhaft Wert=Kanal genommen.)

Und wie greife ich zum Beipiel aus dem Trend-Element direkt in diese Wertreihen?

Also zum Beispiel in den dritten Wert (3.33).



Gruss

McNugget
 
Für die Datenreihe bietet sich ja geradezu ein zweidimensionales Array an.
Damit kann man dann z.B. 20 Messreihen mit je 100 Messwerten erfassen.
Das Problem ist nun aber das Histogramm das bei mir ums Verrecken keinen Zugriff auf einen Teil des Array macht. Ich bekomme es nicht geregelt dort eine Auswahl einzutragen die nur eine Datenreihe über einen Indes annimmt. Aber mit Pointern kommt das Teil klar und daher habe ich eine Lösung erarbeitet die zwar Q&D ist aber funktioniert.
Ich hoffe Du hast keine Angst vor Pointern ;o)

Code:
PROGRAM PLC_PRG
VAR
    MyArray : ARRAY[0..19,0..99] OF REAL;
    pMyArray : POINTER TO  ARRAY[0..19,0..99] OF REAL;
    pMyDummy : POINTER TO  ARRAY[0..99] OF REAL;
    i : INT;     (* aktuelle Messreihe *)
    x :INT;  (* aktueller Messpunkt *)
END_VAR

(* Die FOR-Schleife ist nur zum testen damit da Daten reinkommen *)
FOR x := 0 TO 99 DO
 MyArray[i,x] :=  MyArray[i,x] + 0.1;
END_FOR;

pMyArray := ADR(MyArray[i,0]); (* Setze Pointer auf die Messreihe i *)
pMyDummy := pMyArray; (* Kopiere die Pointer adresse *)

So und nun zum Histogramm da habe ich dann als Variable einfach:
PLC_PRG.pMyDummy^
verwendet. Das ^ am Ende ist wichtig!


Vielleicht gibt es ja schönere Lösungen aber die hier verbraucht ausser den paar DWORDs für die Pointer keinen zusätzlichen Speicher.
 
Ähhh... Alle schlottern vor Pointern, da sie sehr abstrakt sind, das tue ich dann auch mal...
(Mal sehen, wie lange ich brauche, es durch learning by doing zu kapieren.)

Was ich nun nicht ganz verstehe: wo gebe ich die 20 Real-Werte rein? Ich muss doch irgendwie Daten reinreichen.
So wie das jetzt ist, ist der Baustein doch abgeschlossen, oder??

LERNEN WILL.. ;-)



Zwischenzeitlich habe ich mal testweise eine Struktur aus meinen Realwertem und einem timestamp gemacht.
Hätte den Vorteil, dass man das dann so mit timestamp wegloggen könnte um es später noch mal mit excel etc. auszuwerten.
Diese Struktur konnte ich wieder gut in mein Array schreiben. Aber ich hab mir auch die Zähne dran ausgebissen, die Werte aus dem Innern des Arrays in das Histogramm zu bekommen.

Sehr sympathisch, dass Du das gleiche Problem hattest, das bedeutet, dass ich zum Teil schon auf dem richtigen Weg war..



Bei der Lösung mit der Struktur, hatte mein Progrämmchen nur 12 ms Laufzeit, finde ich super.



Gruss

McNugget
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Eine Struktur mit Zusatzinformationen hätte halt das Problem das man mit dem Pointer Trick nicht arbeiten kann da das Histogramm das Array mit den Werten ja in einem Block erwartet.

Dann bliebe Dir wohl nur die Alternative eine Schleife zu basteln die Dir aus Deinem Array der Struktur die relevanten Werte in ein extra Anzeige Array umkopiert.
 
Naja... Diese Schleife hätte ich ja schon aus den ersten Beiträgen in diesen Thread. Ich müsste es nur pro Kanal, den ich anzeigen möchte, instanziieren.

Die Histogramm-Anzeige wäre mir aber gar nicht so wichtig wie eine Möglichkeit, die Daten aus dem Controller rauszubekommen und später auf dem PC zu visualisieren.


Noch mal der Vollständigkeit halber: wie bekomme ich das zweidimensionale Array gefüllt?



Gruss

McNugget
 
... und wüsste jemand ein ausführliches How-To, wie man Schleifen, Schieberegister und Arrays sauber in ST schreibt?

Gruss und schönen Abend noch

McNugget
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... ein how-to-do für ST-Programmierung im Allgemeinen und Schleifen-Erstellung im Besonderen kenne ich nicht - man kann sich aber auch Schritt-für-Schritt da herein-arbeiten - ggf. in dem man seine bisherige Arbeit ins Forum stellt und bewerten läßt.

Gruß
LL
 
Guten Morgen.

Hmm, Na dann werde ich mich mal weiter reinfuchsen.
Pascal Büchlein noch mal anlesen..


Bezugnehmend auf den Beitrag von zotos von gestern 14:27 Uhr:
...und wie bekomme ich nun dieses zweidimensionale Array gefüllt?

Gruss

McNugget
 
In Dem Du die Werte in die einzelnen Zellen hineinschreibst z.B. mit einer Schleife.

Ein zweidimensionales Array ist ja quasi eine Tabelle mit Zeilen und Spalten. Daher hat es eine x und eine y Koordinate.

Datenspeicher[x,y] := MyRealValue;

Im Prinzip musst DU doch nur den Code von Larry um die Information einer Spalte erweitern.
 
Zurück
Oben