Mittelwertbildung

Zuviel Werbung?
-> Hier kostenlos registrieren
Lineare Mittelwertbildung und Archiv über X Array Elemente

Hallo an alle,
mein Ansatz ist folgender.Ich baue einen Datenbaustein der nur eine Variable hat,ein Array[1..X] of real.Die Größe des Array ist beliebig(nur durch S7 geschränkt) und realisiert das Messarchiv .
Der gebaute Fb(Linear_Mittelwert_real) macht dann folgendes, er füllt das Array vollständig und bildet über alle Elemente den linearen Mittelwert unabhängig von der Größe des Array.Ist das Archiv voll fängt der FB wieder bei der ersten Zelle an.
Die Archivierung erfolgt getaktet(bei O3X nicht nötig da selbst ein Takt),aus der Taktfrequenz und der Größe des Archives ergibt sich die Geschwindigkeitsänderung des Mittelwertes.Beispiel Takt:=100ms,DB:=100 Elemente, somit währe das Archiv nach 10Sekunden vollständig neu gefüllt worden.

Awl-Quelle liegt bei.
Beispielprogramm liedt bei.
Aufrufgrafik liegt bei.

AWL Textcode:
Code:
FUNCTION_BLOCK "Linear_Mittelwert_real"
TITLE =
VERSION : 0.1


VAR_INPUT
  Takt : BOOL ;    //Externer Impuls
  Real_Messwert : REAL ;    //Messwert normiert auf real
  DB_NR : INT ;    //Nr des DB ,der DB ist Array[1..X] of real Ausschließlich
END_VAR
VAR_OUTPUT
  Linearer_Mittelwert : REAL ;    
END_VAR
VAR
  Pointer_Speicher_Stat : DWORD ;    
END_VAR
VAR_TEMP
  DB_NR_intern : INT ;    
  Pointer_Speicher_temp : DWORD ;    
  Pointer_schleife : DWORD ;    
  schleife : INT ;    
  SummeMesswert : REAL ;    
  Anzahl_Messelemente : DINT ;    
END_VAR
BEGIN
NETWORK
TITLE =Messwertspeicherung in einem beliebig großem Array of real(DB)
//Datensammlung des Messwertes.Bei jeder messung wird der Wert hochlaufend in 
//eine Zelle geschrieben.Ist der DB voll wird mit der ersten zelle 
//wieder angefangen.
      UN    #Takt; //wenn Takt=false keine Bearbeitung
      SPB   Ende; 
//***************************************************
      L     #DB_NR; //Indirektes öffnen des Messpeicher DB
      T     #DB_NR_intern; 
      AUF   DB [#DB_NR_intern]; 
//***************************************************
      L     #Pointer_Speicher_Stat; //Übergabe statischen an Temp zwecks Indirekte
      T     #Pointer_Speicher_temp; 
//++++++++++++++++++++++++++++++
      L     #Real_Messwert; //Wertablage in Mess_speicher db
      T     DBD [#Pointer_Speicher_temp]; 
//++++++++++++++++++++++++++++++
      L     P#4.0; //Pointererhöhung für nächste Messspeicherung
      L     #Pointer_Speicher_Stat; 
      +D    ; 
      T     #Pointer_Speicher_Stat; 
//***************************************************
//Berechnen der Grenzen des Messspeicher DB und Neubelegung des Pointers mit null
      L     #Pointer_Speicher_Stat; //Adresse des Pointers ermitteln
      SRD   3; //umwandeln nach dint,int
      L     DBLG; //laden der DB Länge in byte
      >=D   ; //wenn der Pointer >= ist als die Anzahl der Byte`des DB
      SPBN  neu; 
      L     P#0.0; //Neubelegung des Pointer
      T     #Pointer_Speicher_Stat; 
neu:  NOP   0; 


NETWORK
TITLE =Lineare Mittelwertbildung über alle Elemente des Array`s (DB)

      L     P#0.0; //Pointer auf erstes Messelement legen
      T     #Pointer_schleife; 
      L     0.000000e+000; 
      T     #SummeMesswert; //vorbelegung Summe Messwert mit null
      L     DBLG; //Datenbausteinlänge in Byte
      L     4; 
      /D    ; 
      T     #Anzahl_Messelemente; 
next: T     #schleife; 
      L     DBD [#Pointer_schleife]; //lade Messelement
      L     #SummeMesswert; 
      +R    ; 
      T     #SummeMesswert; 
      L     P#4.0; 
      L     #Pointer_schleife; 
      +D    ; 
      T     #Pointer_schleife; 

      L     #schleife; 
      LOOP  next; 
//*************************************************
      L     #SummeMesswert; 
      L     #Anzahl_Messelemente; 
      DTR   ; //Umwandlung in real
      /R    ; //Die summe der Messungen durch Anzahl ist Mittelwert
      T     #Linearer_Mittelwert; 
Ende: NOP   0; 
      SET   ; 
      SAVE  ; 
END_FUNCTION_BLOCK
 

Anhänge

  • Mittelwert.zip
    47,5 KB · Aufrufe: 52
  • OB35_Mittelwert.JPG
    OB35_Mittelwert.JPG
    43,5 KB · Aufrufe: 54
jetz hab ich mir dann auch mal die bilder angeguckt

deine anfangsadresse ist NICHT 8

Hm, ja stimmt - die Adresse im DB1 für das RealArray[0] geht mit 0.0 los!

1) Vermutlich muss ich das immer händisch nachholen, wenn die Startadresse nicht bei 0 losgeht, oder?

2) Jetzt müsste ich ja eigentlich die Adressen von RealArray[0] bis RealArray[7] per Hand abändern - aber ich kann im DB keine Eingaben machen.

Danke!
 
Zuletzt bearbeitet:
Ok vierlagig,

ich versuche es mit "LAR1 P##aRealArray".


Nur zum Verständnis:

Was müsste ich wo abändern, damit es auch so bei mir läuft?

Offensichtlich liegt es ja an der Startadresse..
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, genau - und damit das Ganze wieder zusammenpasst, müsste ich doch jetzt per Hand die Adressen im IDB1 anpassen, so dass die Startadresse eben die 8.0 ist.

Aber genau das geht nicht - es werden keine Änderungen zugelassen, vermutlich weil es ein Instanz-DB ist! Ich hatte aber doch auch keine Möglichkeit, beim Generieren des DBs die Adresse bei 8 beginnen zu lassen...

Frage:

Was macht man in diesem Fall in der Praxis - wie kann die oben genannte Änderung dennoch vorgenommen werden?

Danke!
 
Ja, genau - und damit das Ganze wieder zusammenpasst, müsste ich doch jetzt per Hand die Adressen im IDB1 anpassen, so dass die Startadresse eben die 8.0 ist.

Aber genau das geht nicht - es werden keine Änderungen zugelassen, vermutlich weil es ein Instanz-DB ist! Ich hatte aber doch auch keine Möglichkeit, beim Generieren des DBs die Adresse bei 8 beginnen zu lassen...

Frage:

Was macht man in diesem Fall in der Praxis - wie kann die oben genannte Änderung dennoch vorgenommen werden?

Danke!

alter, willste mich verarschen???
das ist nicht lustig!

1. LAR1
2. vielleicht statt der acht in zeile 85.879372 eine 0 hinschreiben
 
Hallo Leute,

mal ein ganz anderer Ansatz ganz ohne Arrays.

Ich verwende meistens die gleitende Mittelwertbildung. Vorteil, kommt ganz ohne speicherfressendes Array aus. Nachteil es ergibt sich immer ein kleiner Fehler, der aber meist vernachlässigbar ist.

Hier die AWL Quelle:

Code:
FUNCTION "VM" : VOID
TITLE =Gleitende Mittelwertbildung
AUTHOR : VIS_Blum
FAMILY : CALC
NAME : FC_169
VERSION : 1.0
 
VAR_INPUT
  AKT : REAL ; //Aktueller Wert
  Tiefe : INT ; //Filtertiefe
END_VAR
VAR_IN_OUT
  Mittel : REAL ; //Mittelwert
END_VAR
VAR_TEMP
  Faktor : REAL ; //Bewertung, Stärke des Mittelwertes
  Divisor : REAL ; //Filtertiefe für Mittelwert
END_VAR
BEGIN
NETWORK
TITLE =
      L     2; 
      L     #Tiefe; 
      >I    ; 
      SPB   AUS; 
      L     #Tiefe; 
      DTR   ; 
      T     #Divisor; 
      L     #Tiefe; 
      +     -1; 
      DTR   ; 
      T     #Faktor; 
      L     #Mittel; 
      L     #Faktor; 
      *R    ; 
      L     #AKT; 
      +R    ; 
      L     #Divisor; 
      /R    ; 
      T     #Mittel; 
      BEA   ; 
AUS:  L     #AKT; 
      T     #Mittel; 
END_FUNCTION

Vielleicht hilft es ja,

Gruß Rolf
 
Ich glaube der Kollege versucht den Instanz DB so zu ändern, daß sein Array bei adresse 8 anfängt.

Yep, das wäre mein Vorhaben gewesen!

Aber offensichtlich ist das bei einem Instanz-DB nicht machbar...

Vermutlich legt der Instanz-DB seine erste Adresse immer bei 0 an. Habe auch keine Möglichkeit gefunden, im Instanz-DB die Startadresse festzulegen.

Grüße
pinolino
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du kannst den IDB über die Schnittstellen des Bausteins parametrieren.
Wenn Du vor dem ARRAY 0..7 noch ein DW als dummy anlegst, wird sich die Adresse des arrays im IDB um 4 Byte verschieben.
Das wäre die einzige mir bekannte möglichkeit das zu tun, aber es macht glaub ich mehr sinn, die änderung im code vor zu nehmen.
 
Du kannst den IDB über die Schnittstellen des Bausteins parametrieren.
Wenn Du vor dem ARRAY 0..7 noch ein DW als dummy anlegst, wird sich die Adresse des arrays im IDB um 4 Byte verschieben.

Hallo PBO-WE,

ich nehme an du meinst mit "über die Schnittstellen des Bausteins" den Deklarationsbereich des Funktionsbausteins?

Gibt es echt keine Möglichkeit, z.B. die Adressen eines IDB im Baustein selber zu ändern?
 
ich nehme an du meinst mit "über die Schnittstellen des Bausteins" den Deklarationsbereich des Funktionsbausteins?
zu ändern?

Genau den meine ich. Sorry, kenn mich mit den Begrifflichkeiten nicht so super aus, da ich mir mein Wissen überwiegend durch experimentieren beigebracht habe. :confused:

Mir ist nicht bekannt, daß man den IDB irgendwie bearbeiten kann.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kein Problem...

Es ist nur so, dass ich ziemliche Anfängerin bin und daher nicht immer genau weiß, was die Profis meinen, wenn die Dinge nicht genau bei ihrem Namen genannt werden... ;)

Müsste dieses Dummy-Array eigentlich unbedingt in der statischen-Schnittstelle (also dort wo auch das Array deklariert ist) eingefügt werden, oder ginge es z.B. auch im TEMP-Bereich?

Danke!
 
Im Temp-Bereich ist es leider nicht möglich, da diese Variablen nicht im IDB abgelegt werden, sondern nach jedem Bausteinaufruf verloren gehen.
Im IN, Out, IN/OUT oder Statischen Bereich ist es möglich.
 
Aja vielen Dank, PBO-WE!

Somit muss dieses Dummy-Array also nicht zwangsweise im gleichen Bereich eingefügt werden, wie das bestehende, richtig?
 
Ok vierlagig, habe verstanden - zumindest das. ;)

Hätte man diesen "Fehler" denn bei der Programmierung überhaupt verhindern können, außer dass man den Code

LAR1 P##aRealArray

verwendet hätte?

Ich meine, aus welchem Grund wurde denn die Startadresse des Arrays im IDB beim Aufruf des FBs falsch angelegt? Der IDB muss doch eigentlich "wissen", welche Adressbereiche im FB deklariert sind. :confused:

Thanks!
 
Ok vierlagig, habe verstanden - zumindest das. ;)

Hätte man diesen "Fehler" denn bei der Programmierung überhaupt verhindern können, außer dass man den Code

LAR1 P##aRealArray

verwendet hätte?

Ich meine, aus welchem Grund wurde denn die Startadresse des Arrays im IDB beim Aufruf des FBs falsch angelegt? Der IDB muss doch eigentlich "wissen", welche Adressbereiche im FB deklariert sind. :confused:

Thanks!

hier wurde nischtens falsch angelegt, das war einfach nur ein ziemlich dämlicher programmierfehler. wenn die startadresse nun mal 0 ist, dann ist sie 0 und NICHT 8 ...
 
Zurück
Oben