# Ringpuffer mit Mittelwert



## taucherd (8 Februar 2008)

Habe diverse Programmteile vom Forum zu einem Ringpuffer zusammengefügt. Soweit funktioniert es ja aber es gibt ein Problem.
den Datenanfang beim Abspeichern: dieser wird im NW4 erst aktualisiert wenn das Datenende erreicht wurde.
Habe es schon mit einer Schleife versucht, aber irgendwie .....

Es gibt sicher eine Lösung dafür, aber leider gelingt es mir nicht.
habe das Programm hinzugefügt, danke.

Schön langsam wird es mit den Pointern :-D


----------



## godi (8 Februar 2008)

Habe kurz mal dein Programm überflogen...
Warum Bildest du dir immer einen Pointer mit SLD 3 und dann Speicherst das ab damit du Speicherindirekt adressieren kannst?

zb:

```
T     #Index               
      SLD   3                       
      T     #Ind_pointer                // Pointer-Adresse
      L     #Real_IN
      T     DBD [#Ind_pointer]         //Das ist eine speicherindirekte adressierung! Du greifst auf das Byte zu das in deiner Variable Ind_pointer steht!
```

das sollte so sein:


```
T     #Index               
      SLD   3 
      LAR 1               
      L     #Real_IN
      T     DBD [AR1,P#0.0] //Das ist eine Adressregister indirekte adressierung! Du greifst auf die Adresse zu die im AR 1 steht mit dem Offset 0.0!
```


----------



## taucherd (8 Februar 2008)

godi schrieb:


> Habe kurz mal dein Programm überflogen...
> Warum Bildest du dir immer einen Pointer mit SLD 3 und dann Speicherst das ab damit du Speicherindirekt adressieren kannst?
> 
> zb:
> ...



________________________________________
Wenn der Pointer für den Speicherort nicht indirekt generiert wird, dann wird immer bei der Adresse 0 begonnen und ich möchte aber sagen von wo der Speicherbereich beginnt wo die Daten abgespeichert werden. möchte mit einem DB mehrere Mittelwertbildungen abdecken.

Der Index arbeitet schon noch richtig aber der Pointer beginnt trotzdem bei Adresse 0!


----------



## godi (8 Februar 2008)

taucherd schrieb:


> ________________________________________
> Wenn der Pointer für den Speicherort nicht indirekt generiert wird, dann wird immer bei der Adresse 0 begonnen und ich möchte aber sagen von wo der Speicherbereich beginnt wo die Daten abgespeichert werden. möchte mit einem DB mehrere Mittelwertbildungen abdecken.
> 
> Der Index arbeitet schon noch richtig aber der Pointer beginnt trotzdem bei Adresse 0!



Hast du die Kommentare gelesen und verstanden die ich bei den Beispielen dazugeschrieben habe?


----------



## taucherd (8 Februar 2008)

godi schrieb:


> Hast du die Kommentare gelesen und verstanden die ich bei den Beispielen dazugeschrieben habe?




OK, das stimmt - aber ich brauche den offset mit null nicht! oder ich habe es nicht verstanden?
das behebt das problem auch nicht - leider! 
den bei einem neustart, wenn im Index_Ringspeicher 0 drinnen steht und ich sage die daten beginnen bei adresse 100 dann wird der db von adresse 0 - 100 genauso mit dem real_in wert überschrieben.
und ganu das möchte ich verhindern, da ich mit einem zweiten fc auf diesen bereich schreibe und zugreife.

Offset: P#100.0 beginnt der Pointer natürlich bei 100.0.
jetzt gebe ich bei datenanfang die adresse 200 an und der speicherort ist bei 300 und der mittelwert wird ab 200 gebildet?


----------



## Markus (8 Februar 2008)

habe dein programm jetz nicht angesehen, muss hier grad erst alles neu installieren auf der neuen mühle....

aber nur zum thema mittelwerbildung eine kleine anregung:



harrylask schrieb:


> M=LM+((Z-LM)/N)
> 
> M=Mittelwert
> LM=Letzter Mittelwert
> ...


 
vielleicht machst du die sache zu kompliziert?

habe mit einen schönen fc gemacht der mir mittel, min und max wert ausgibt und eingänge für trigger und reset hat - aber leider komme ich da gerade nicht dran...


----------



## taucherd (8 Februar 2008)

Markus schrieb:


> habe dein programm jetz nicht angesehen, muss hier grad erst alles neu installieren auf der neuen mühle....
> 
> aber nur zum thema mittelwerbildung eine kleine anregung:
> 
> ...



Ist das nicht eine "Signalglättung" ,ein schöner Einzweiler.
beim anfahren der anlage braucht es ewig bis der wirkliche mittelwert erreicht ist, wenn die anzahl zu hoch ist, oder?
aber ich werde es nochmals ansehen - danke


----------



## godi (8 Februar 2008)

Dein Index_Ringspeicher sollte eine IN_OUT Variable sein.
Den Offset von deinem Pointer könntest du auch von Außen über eine IN Variable angeben.

zb:


> L     #Index
> L     #Offset_Index
> +D
> SLD   3
> ...


----------



## volker (8 Februar 2008)

ein paar bausteine die dir weiterhelfen findest du auf meiner hp im download unter sps/s7
guckst du mal filo_lifo.zip und db_auswerten.zip


----------



## Kai (9 Februar 2008)

taucherd schrieb:


> Habe diverse Programmteile vom Forum zu einem Ringpuffer zusammengefügt. Soweit funktioniert es ja aber es gibt ein Problem.


 
Wenn Du nicht unbedingt mit einem Ringpuffer arbeiten musst, dann helfen Dir vielleicht die beiden folgenden Bausteine weiter.

Der FC100 FILO liest Werte im Datenformat REAL ein und speichert die Werte in einem DB:


```
FUNCTION FC 100 : INT
TITLE =FILO-Speicher
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : FILO
VERSION : 1.0
 
VAR_INPUT
  SPEICHER : POINTER ;  
  LAENGE : INT ;    
  WERT : REAL ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ;  
  AR1_REGISTER : DWORD ;    
  DB_NUMMER : WORD ;    
  BEREICHSZEIGER : DWORD ;  
  ZWISCHENWERT : REAL ; 
  SCHLEIFE : INT ;  
  ZAEHLER : REAL ;  
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =FILO-Speicher
 
      L     P##SPEICHER; // POINTER
      LAR1  ; 
 
      L     W [AR1,P#0.0]; // DB-Nummer
      T     #DB_NUMMER; 
 
      AUF   DB [#DB_NUMMER]; 
 
      L     D [AR1,P#2.0]; // Bereichszeiger
      LAR1  ; 
 
      L     #WERT; // Wert
      T     #ZWISCHENWERT; // Wert => Zwischenwert
 
      L     #LAENGE; // Länge
M01:  T     #SCHLEIFE; // Schleife
 
      L     D [AR1,P#0.0]; // Wert
      L     #ZWISCHENWERT; // Zwischenwert
      T     D [AR1,P#0.0]; // Zwischenwert => Wert
      TAK   ; 
      T     #ZWISCHENWERT; // Wert => Zwischenwert 
 
      L     P#4.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; // Schleife
      LOOP  M01; 
 
NETWORK
TITLE =DB-Register und Adressregister AR1 wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Der FC110 MITTELWERT bildet aus den im DB gespeicherten Werten einen Mittelwert im Datenformat REAL nach folgender Formel:



> M = LM + ( (Z - LM ) / N)
> 
> M = Mittelwert
> LM = Letzter Mittelwert
> ...


 

```
FUNCTION FC 110 : INT
TITLE =Mittelwert
//Mittelwert
//
//M = LM + ((Z - LM) / N)
//
//M  = Mittelwert
//LM = Letzter Mittelwert
//Z  = Wert
//N  = Anzahl Werte
//   
//Beispiel:
// 
//Man hat einen Mittelwert, der aus 10 Werten gebildet wird. Wenn jetzt ein 
//neue Wert dazu addiert wird, hat man 11 Werte. Also muss 1/10 des
//Mittelwertes subtrahiert werden, damit man insgesamt wieder 10 Werte hat.
//   
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : FILO
VERSION : 1.0
 
VAR_INPUT
  SPEICHER : POINTER ;    
  LAENGE : INT ;    
END_VAR
VAR_OUTPUT
  MITTELWERT : REAL ;   
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ;  
  AR1_REGISTER : DWORD ;    
  DB_NUMMER : WORD ;    
  BEREICHSZEIGER : DWORD ;  
  ZWISCHENWERT : REAL ; 
  SCHLEIFE : INT ;  
  ZAEHLER : REAL ;  
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =Mittelwert
 
      L     P##SPEICHER; // POINTER
      LAR1  ; 
 
      L     W [AR1,P#0.0]; // DB-Nummer
      T     #DB_NUMMER; 
 
      AUF   DB [#DB_NUMMER]; 
 
      L     D [AR1,P#2.0]; // Bereichszeiger
      LAR1  ; 
 
      L     0.000000e+000; 
      T     #ZWISCHENWERT; // Letzter Mittelwert
 
      L     1.000000e+000; 
      T     #ZAEHLER; // Anzahl Werte
 
      L     #LAENGE; // Länge
M01:  T     #SCHLEIFE; // Schleife
 
      L     D [AR1,P#0.0]; // Wert
      L     #ZWISCHENWERT; // Letzter Mittelwert
      -R    ; 
      L     #ZAEHLER; // Anzahl Werte
      /R    ; 
      L     #ZWISCHENWERT; // Letzter Mittelwert
      +R    ; 
      T     #ZWISCHENWERT; // Mittelwert
 
      L     #ZAEHLER; // Anzahl Messungen
      L     1.000000e+000; 
      +R    ; 
      T     #ZAEHLER; // Anzahl Messungen
 
      L     P#4.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; // Schleife
      LOOP  M01; 
 
      L     #ZWISCHENWERT; // Mittelwert
      T     #MITTELWERT; // Mittelwert
 
NETWORK
TITLE =DB-Register und Adressregister AR1 wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## der_iwan (18 Mai 2011)

*eine Frage*

Hallo und guten Tag
Ich habe mir die beiden Bausteinen von Kai in mein Programm übertragen.
CPU Typ : 314-1AF10-0AB0.
Die CPU geht in stop und meldet: Bereichsfehler beim lesen
Ursache: 
Sie haben bei der bereichsübergreifenden registerindirekten Adressierung einen unzulässigen Operandenbereich verwendet. Die Bereichskennung der Zugriffsadresse (Bit 24 -31) ist unzulässig.
Behebung: 
Verwenden Sie einen Pointer mit korrekter Bereichskennung. 

den Stop habe ich mit OB121 abgefangen, damit die Maschine weiter produzieren kann

Bei einer CPU 318 (Vipa 315)funktionieren die beiden Bausteine wunderbar.

womit könnte das zusammen hängen?

der_iwan


----------



## Larry Laffer (18 Mai 2011)

Hallo,
welche DB-Nummer hast du denn verwendet ?
Und ... ggf. auch wieviele Werte ?

Gruß
Larry


----------



## SoftMachine (18 Mai 2011)

Hallo,
zu hohe DB-Nummern bei der CPU 314

318 kann schon richtig was...

Gruss


----------



## SoftMachine (18 Mai 2011)

Larry Laffer schrieb:


> Hallo,
> welche DB-Nummer hast du denn verwendet ?
> Und ... ggf. auch wieviele Werte ?
> 
> ...


 

Hallo LL !

Warst schneller, 
denke aber wir meinen das gleiche ...

Gruss


----------



## der_iwan (18 Mai 2011)

Hallo 
Ich habe  den DB 200 genommen.
Laut Leistungsdaten kann die CPU bis DB511

der_iwan


----------



## Larry Laffer (18 Mai 2011)

Und jetzt auch noch die Antwort darauf :


Larry Laffer schrieb:


> Und ... ggf. auch wieviele Werte ?


 

@Softmaschine:
Hast Recht - das war so mein erster Gedanke (weil immer wieder gerne gemacht) ...

Gruß
Larry


----------



## der_iwan (18 Mai 2011)

Hallo
Ich habe genau wie im Beispiel von Kai 10 Werte.

Es sind bei beiden CPU ist die gleichen Bausteine.

der_iwan


----------



## SoftMachine (18 Mai 2011)

Hm,
DB auch übertragen ... ?

Gruss


----------



## der_iwan (18 Mai 2011)

SoftMachine schrieb:


> Hm,
> DB auch übertragen ... ?
> 
> Gruss


 
Ja,der DB ist übertragen

der_iwan


----------



## Larry Laffer (18 Mai 2011)

Sorry ... da habe ich dann auch keine gute Idee mehr.
Welche Programmzeile wird denn angemeckert, wenn du den beschriebenen Fehler bekommst ?
Was macht dein Programm sonst noch so ?

Gruß
Larry


----------



## der_iwan (18 Mai 2011)

Hallo
Baugruppenzustand meldet:

Baugruppenträger: 0
Steckplatz: 2
Ereignis 1 von 10: Ereignis-ID 16# 2524
Bereichsfehler beim Lesen 
Falsche Bereichskennung: 0
Angeforderter OB: Programmierfehler-OB (OB 121)
Prioritätsklasse: 1
interner Fehler, kommendes Ereignis
13:50:53.673 18.05.2011

sonst ist mein Programm in einer Spritzgiessmaschine.
Ich wollte mir anschauen, ob ein bestimmter Wegpunkt zu einem bestimmten Ereignis immer den gleichen Wert hat.

der_iwan


----------



## Larry Laffer (18 Mai 2011)

... ich meinte eigentlich :
Wird dir die Taste "Baustein öffnen" in der Diagnose angeboten und wenn ja ... wenn du sie benutzt ... in welcher Zeile des FC's stehst du dann ?

Gruß
Larry


----------



## der_iwan (18 Mai 2011)

Hallo
Die Taste Baustein öffnen wird nicht angeboten

der_iwan


----------



## Kai (18 Mai 2011)

Funktionieren vielleicht die folgenden, leicht geänderten Programmbausteine für den FIFO und die Mittelwertbildung?

http://www.sps-forum.de/showpost.php?p=217371&postcount=11

Gruß Kai


----------



## der_iwan (18 Mai 2011)

@ Kai
werde ich morgen gleich als erstes austesten

der_iwan


----------



## Kai (18 Mai 2011)

der_iwan schrieb:


> Ich habe mir die beiden Bausteinen von Kai in mein Programm übertragen.


 


der_iwan schrieb:


> Ich wollte mir anschauen, ob ein bestimmter Wegpunkt zu einem bestimmten Ereignis immer den gleichen Wert hat.


 
Verwendest Du nur den Programmbaustein für den FIFO oder auch den Programmbaustein für die Mittelwertbildung?

Die beiden Programmbausteine können ja unabhängig voneinander verwendet werden.

Gruß Kai


----------



## der_iwan (19 Mai 2011)

Hallo



Kai schrieb:


> Funktionieren vielleicht die folgenden, leicht geänderten Programmbausteine für den FIFO und die Mittelwertbildung?
> 
> http://www.sps-forum.de/showpost.php?p=217371&postcount=11
> 
> Gruß Kai


 
Damit hat es auf Anhieb funktioniert. Danke 

P.S. Ich nutze nur den FIFO Baustein


----------



## Kai (19 Mai 2011)

Vielen Dank für die Rückmeldung.

Gruß Kai


----------



## SoftMachine (19 Mai 2011)

Na, das is´doch ein Erfolg, so was lieb´ich ...  

Gruss an beide


----------

