# FIFO mit S7 ????



## moclam (3 März 2010)

Respekt an alle Teilnehmer.
Ich merke es gibt richtige Profis hier im Forum :TOOL:.
ich bin ganz neue mit der Sache SPS S7- System und muss schon schwitzen. Für mein Praktikum muss ich eine CIP-Anlage programmieren.
Mehrere Verbraucher Anforderungen sollen nach dem FIFO-Verfahren verarbeitet werden. Die Firma braucht das als Standard Baustein weil sie es fast für jede Projekt brauchen.
Habe hier durchgesucht und FIFO von Volker gefunden. Aber habe es überhaupt nicht kappiert was da gemacht wird.

a) Wie soll ich das ganze anfangen?

b) Kann jemand mir das bitte richtig auskommentieren? habe bis jetzt nur mit FUP zu tun gehabt.

c) Am Anfang öffnet er den DB(der als speicher dienen soll hoffe ich kappiert zu haben!!!!!!). Ich habe 30 Teilnehmer wie soll den DB aussehen?

d) Die Variablen #Datenanfang(Anfangs- oder Endadresse des DBs?) und #Datenende(Anfangs oder Endadresse des DBs?) ) sind Anfangs- und Endadresse der DB oder umgekeht? oder gelesenen Daten(Anfangs oder Endadresse des DBs?) )

Vielen Dank zuerst mal für Ihre Bemühungen

Moclam


----------



## Larry Laffer (3 März 2010)

Hallo,
ich finde, dass das Beispiel eigentlich ganz gut dokumentiert ist. Es ist ja nicht mal vergessen worden, auf die grundsätzliche Arbeitsweise eines FIFO's einzugehen.

Solche Sachen lassen sich NICHT in FUP programmieren. Wieso eigentlich immer FUP ?

Wie groß soll dein Datenbereich sein ?
Bytes oder Worte oder Doppelworte ? Oder noch mehr ?

Gruß
LL


----------



## moclam (3 März 2010)

Vielen Dank zuerst mal Larry,

sei mir nicht böse, die Firma will es so in FUP haben, wenn es ginge, da ich danach weg gehe und sie müssen benutzen.
Es werden 25 Teilnehmer sein und WORD.
Ich will auf jeden Fall AWL lernen deswegen würde mich freuen wenn ich auf jede Zeile ein Kommentar gehabt hätte

Vielen Dank noch mal

Moclam


----------



## micha2010 (3 März 2010)

Hallo moclam

Hab ich das richtig verstanden das du in ersterlinie erst mal AWL verstehen willst?
Wenn das so sein sollte kann ich dir nur raten in der Syntaxhilfe nachzuschauen. Dann wirst du es serh schnell verstehen. Hab früher auch in FUP programmiert und kann nur sagen das man es dadurch sehr schnell versteht. 
Am besten mal kleinere programme als übung machen.


----------



## vierlagig (3 März 2010)

Larry Laffer schrieb:


> H
> Solche Sachen lassen sich NICHT in FUP programmieren.



GERÜCHT! 


```
*
FUNCTION_BLOCK FB 10
TITLE =
VERSION : 0.1


VAR_INPUT
  xPulse : BOOL ;	
  wIn : WORD ;	
END_VAR
VAR_OUTPUT
  wOut : WORD ;	
END_VAR
VAR
  xHelpFlag : BOOL ;	
  wArrayOfWord : ARRAY  [0 .. 7 ] OF WORD ;	
END_VAR
VAR_TEMP
  xHelp : BOOL ;	
END_VAR
BEGIN
NETWORK
TITLE =

      U     #xPulse; 
      FP    #xHelpFlag; 
      SPBN  end; 
NETWORK
TITLE =

      U(    ; 
      L     #wArrayOfWord[7]; 
      T     #wOut; 
      SET   ; 
      SAVE  ; 
      CLR   ; 
      U     BIE; 
      )     ; 
      SPBNB _001; 
      L     #wArrayOfWord[6]; 
      T     #wArrayOfWord[7]; 
_001: NOP   0; 
NETWORK
TITLE =

      U(    ; 
      L     #wArrayOfWord[5]; 
      T     #wArrayOfWord[6]; 
      SET   ; 
      SAVE  ; 
      CLR   ; 
      U     BIE; 
      )     ; 
      SPBNB _002; 
      L     #wArrayOfWord[4]; 
      T     #wArrayOfWord[5]; 
_002: NOP   0; 
NETWORK
TITLE =

      U(    ; 
      L     #wArrayOfWord[3]; 
      T     #wArrayOfWord[4]; 
      SET   ; 
      SAVE  ; 
      CLR   ; 
      U     BIE; 
      )     ; 
      SPBNB _003; 
      L     #wArrayOfWord[2]; 
      T     #wArrayOfWord[3]; 
_003: NOP   0; 
NETWORK
TITLE =

      U(    ; 
      L     #wArrayOfWord[1]; 
      T     #wArrayOfWord[2]; 
      SET   ; 
      SAVE  ; 
      CLR   ; 
      U     BIE; 
      )     ; 
      SPBNB _004; 
      L     #wArrayOfWord[0]; 
      T     #wArrayOfWord[1]; 
_004: NOP   0; 
NETWORK
TITLE =

      L     #wIn; 
      T     #wArrayOfWord[0]; 
      NOP   0; 
NETWORK
TITLE =

end:  O     #xHelp; 
      ON    #xHelp; 
      SAVE  ; 
END_FUNCTION_BLOCK
```


----------



## moclam (3 März 2010)

*FIFO mit S7*

Hallo Micha2010,

Danke für den Tipps
Das mache ich auf jeden Fall.
Kannst du mir irgendwelches empfehlen?

Das großes Problem wie oben erwähnt ist die Firma, die FUP
haben will aber wenn es nicht geht dann werden sie wahrscheinlich damit leben müssen.

Besonders es muss ein Standardbaustein sein.

==> sie brauchen drin nicht zu schauen wenn es läuft.

Moclam


----------



## Larry Laffer (3 März 2010)

@4L:
Wo ist denn das eine Schleife ?
Soll der TE den Anweisungsblock für seine 25 Worte dann so machen ? Ist für mich OK, wenn er das so will.

@moclam:
erstmal damit wir von der gleichen Sachen reden. Hier ist der fragliche Beitrag von Volker :
	
	



```
AUF   #Datenbaustein      //Typ: Block_DB   [COLOR=red]//hier[/COLOR][COLOR=red] muss dein DB hin ...
[/COLOR]      L     #Datenende          //Typ: INT  [COLOR=red]//die Anzahl der zu verarbeitenden Elemente - bei dir wären es 25
[/COLOR]      L     1
      -I    
      T     #index              //Typ: DINT
anf:  NOP   0                   //Schleifenanfang
      L     #index
      SLD   4                   //pointer erzeugen [COLOR=red]  //von SLD 3 auf SLD 4 geändert, weil du ja mit Worten arbeiten willst[/COLOR]
[COLOR=red]                                      // aus deiner Adresse wird so ein Bit-Pointer für die indirekte Adressierung erzeugt
[/COLOR]      LAR1                      //in das Adressregister laden
      L     DBW [AR1,P#0.0]  [COLOR=red]// hier habe ich auch wieder geändert, da du ja mit Worten arbeiten willst
[/COLOR]      T     DBW [AR1,P#2.0]
      L     #index
      L     1
      -I                        //Index um 1 verringern
      T     #index
      L     1
      +I    
      L     #Datenanfang        //Typ: INT [COLOR=red] // in deinem Fall = 1[/COLOR]
      <=I                       //prüfen ob fertig
      SPB   ende                //wenn ja ende
      SPA   anf                 //sonst schleife wiederholen
ende: NOP   0
      L     #Eintrag            //Typ: WORD
      T     DBW [AR1,P#0.0]     //neuen Wert eintragen
```
.. das müßte es nun gewesen sein. Versuch dich mal daran.
Leider lassen sich diese (etwas komplexeren Dinge) nicht in FUP machen.
Aber vielleicht hilft es dir ja ...

Gruß
LL


----------



## vierlagig (3 März 2010)

Larry Laffer schrieb:


> @4L:
> Wo ist denn das eine Schleife ?
> Soll der TE den Anweisungsblock für seine 25 Worte dann so machen ? Ist für mich OK, wenn er das so will.



schleife? wieso? wofür? aber kann ich dir auch noch bauen, kein problem... dieser fifo da oben pulst auf anforderung, so wie ich mir einen fifo halt vorstelle


----------



## moclam (3 März 2010)

finde ech super, dass alle sich Mühe geben um mir zu helfen. Hoffe werde bald so wie ihr sein.

@Vierlagig

dein 1. Code habe ich super gut verstanden weil ich mehr in Richtung Hochsprache mich besser fühle.
Ich arbeite gerade mit dem und habe noch ein kleines Problem.

Habe zur INPUT noch #Datenbaustein( da ich am Ende mein FIFO als  Standardbaustein haben muss) eingegeben. ;-)

Habe in STAT #wArrayOfWord Array [<1..32>] of <word> deklariert aber es gibt immer eine Fehlermeldung  weiss nicht warum.

Ich muss es meiner Meinung nach danach #wArrayOfWord zu #Datenbaustein zuweisen aber wie???? weiss ich nicht. 

@Larry

Vielen Dank für Kommentare
Den 1. Code wird mir langsam auch klar aber mache zuerst mal mit dem 1. bis es funktioniert :lol:  Dann mit deinem.


----------



## vierlagig (3 März 2010)

moclam schrieb:


> finde ech super, dass alle sich Mühe geben um mir zu helfen. Hoffe werde bald so wie ihr sein.



DAS WILLST DU NICHT WIRKLICH! :sm19:



moclam schrieb:


> @Vierlagig



v ... kleines v .... ist das denn wirklich SOOOOOO schwer?



moclam schrieb:


> dein 1. Code habe ich super gut verstanden weil ich mehr in Richtung Hochsprache mich besser fühle.
> Ich arbeite gerade mit dem und habe noch ein kleines Problem.



das war eigentlich nur ein spaß, aber schön, wenn du damit arbeiten willst, viel spaß nur hat das mit hochsprachen nichts zu tun, nichtmal mit hochdeutsch...



moclam schrieb:


> Habe zur INPUT noch #Datenbaustein( da ich am Ende mein FIFO als  Standardbaustein haben muss) eingegeben. ;-)



ich hoffe für dich, dass du noch weißt was du meinst, ich kann es nicht erraten...



moclam schrieb:


> Habe in STAT #wArrayOfWord Array [<1..32>] of <word> deklariert aber es gibt immer eine Fehlermeldung  weiss nicht warum.



schön ist bei fehlermeldungen immer zu wissen, was in der fehlermeldung drin steht. bei mir funktioniert die vergrößerung auf Array [0..31] of word ziemlich gut.



moclam schrieb:


> Ich muss es meiner Meinung nach danach #wArrayOfWord zu #Datenbaustein zuweisen aber wie???? weiss ich nicht.


 
da ich immer noch nicht weiß, was du vorhast: lass es! ... das wArrayOfWord ist doch schon im instanzdatenbaustein drin, was willste mehr???


----------



## moclam (3 März 2010)

*Fifo s7 ????*

@vierlagig

<< DAS WILLST DU NICHT WIRKLICH! :sm19:>>
Ich will es wirklich hoffe es bald tun zu können.

<<v ... kleines v .... ist das denn wirklich SOOOOOO schwer?>>

sorry wenn ich dein Name falsch geschriebe hab.


<<ich hoffe für dich, dass du noch weißt was du meinst, ich kann es nicht erraten...>>

Es muss einfach einen geschlossenen Baustein sein so dass der Anwender nicht wissen muß was drin ist(wie es programiert wurde). Was ihm interessiert ist nur die Schnittstelle(Z.B. welche DB er am Eingang anlägt).
*Du hast aber recht weil ich keins mehr brauche(Habe ja schon den Instanz :TOOL: ). Ich war noch bei FC da ich damit angefangen habe.*

<<schön ist bei fehlermeldungen immer zu wissen, was in der fehlermeldung drin steht. bei mir funktioniert die vergrößerung auf Array [0..31] of word ziemlich gut>>

Leider markiert S7 nur Array [<1..32>] of <word> ROT und sagt nichts weiter dazu     

<<da ich immer noch nicht weiß, was du vorhast: lass es! ... das wArrayOfWord ist doch schon im instanzdatenbaustein drin, was willste mehr??? >>

hat sich erledigt.

Vielen Dank


----------



## vierlagig (3 März 2010)

moclam schrieb:


> Leider markiert S7 nur Array [<1..32>] of <word> ROT und sagt nichts weiter dazu



lass die <><> weg und es geht


----------



## moclam (3 März 2010)

Hallo vierlagig

vielen vielen Dank .

jetzt habe ich keine Fehler Meldung mehr.

Werde jetzt es simulieren und mich nochmal melden

Danke noch mal

Moclam


----------



## Didaddy (4 März 2010)

*FIFO Puffer in SCL*

Da du weiter oben geschrieben hast das du eher von der Hochsprachenseite kommst, dacht ich mir wär SCL vielleicht was für dich.
SCL ist stark an Pascal angelehnt. Brauchste dann halt ein spezielles SCL Paket für Step7 bzw. wenn du Step7 Proffessional hast ist's da drin enthalten.

Hab hier mal nen code für nen FIFO Puffer abgebildet. Der Puffer ist in diesem Beispiel 9 Einträge groß und wird mit Integern gefüllt. 


```
FUNCTION_BLOCK FB211  // FB_FIFO
//  Beschreibung: FB_FIFO
//                In diesem Baustein wurde ein FIFO Puffer (Ring-Puffer) realisiert. 
//                Es gibt zwei Zeiger einen Schreiben Zeiger und einen Lesen Zeiger. In den Puffer werden über diese Zeiger die Daten geschrieben und gelesen.
//                Der Puffer kann bei Bedarf neu initialisiert (gelöscht) werden. Mit dem Fuellen Eingang kann der Puffer zum testen mit vorbelegten
//                Standardwerten gefüllt werden.
//                Schreiben hat in der Regel Vorrang vorm Lesen, das heißt steht z.B Schreiben und Lesen im gleichen Zyklus an, wird zuerst geschrieben und 
//                anschließend gelesen. Ist der Puffer jetzt allerdings voll, würde es durch diese Vorgehensweise ja zu einem Überlauf kommen, daher wird in diesem Fall 
//                zuerst gelesen und anschließend geschrieben.
//                Ansonsten hat Init Vorrang vor Schreiben und Lesen. Das heißt steht Schreiben oder Lesen und eine Initialisierung im selben Zyklus an, dann wird
//                der Auftrag fürs Schreiben bzw. Lesen verworfen.
//                Füllen hat wiederum Vorrang vorm Initialisieren, steht hier beides in einem Zyklus an wird der Puffer initialisiert und anschließend gefüllt.
//  Ersteller:    Didaddy
//  Erstelldatum: 21.01.2010    
//  Änderungen:    
AUTHOR:   Didaddy;
Version:  '1.0';

VAR_INPUT
  nIn               :INT:= 0;                       // Der Wert der in den Puffer geschrieben werden soll
  bSchreiben        :BOOL:= FALSE;                  // Wert in Puffer schreiben (Bei Dauersignal wird der Auftrag nur einmalig ausgeführt (pos.Fl))
  bLesen            :BOOL:= FALSE;                  // Wert aus Puffer lesen (Bei Dauersignal wird der Auftrag nur einmalig ausgeführt (pos.Fl))
  bInit             :BOOL:= FALSE;                  // Puffer neu Initialisieren
  bFuellen          :BOOL:= FALSE;                  // Puffer mit Standardwerten füllen      
END_VAR

VAR_OUTPUT
  nOut              :INT:= 0;                       // Der Wert der aus dem Puffer ausgelesen werden soll
  nZS               :INT:= 1;                       // Zeiger Schreiben    
  nZL               :INT:= 1;                       // Zeiger Lesen
  nAnzVorhDaten     :INT:= 0;                       // Anzahl der vorhandenen Daten im Puffer
  bUeberlauf        :BOOL:= 0;                      // Der älteste Daten Eintrag wurde durch einen neuen überschrieben
END_VAR

CONST
  PG                := 9;                           // Puffergrenze
END_CONST
  
VAR
  bSchreibenAlt     :BOOL:= FALSE;
  bLesenAlt         :BOOL:= FALSE;  
  bInPufferSchreiben:BOOL:= FALSE;  
  bAusPufferLesen   :BOOL:= FALSE;
  bPufferInit       :BOOL:= FALSE; 
  bPufferFuellen    :BOOL:= FALSE;
  nI                :INT:= 0;  
  bVorrangLesen     :BOOL:= FALSE;                  // Das Lesen aus dem Puffer hat Vorrang
  anPuffer          :ARRAY[1..PG] OF INT:= [PG(0)]; 
END_VAR

LABEL
  Schreiben, Lesen;
END_LABEL

(******************** Kommandos entgegennehmen **********************)
// Kommando in Puffer schreiben
IF bSchreiben AND NOT bSchreibenAlt THEN
  bInPufferSchreiben:= TRUE;
END_IF;        
bSchreibenAlt:= bSchreiben;

// Kommando aus Puffer Lesen
IF bLesen AND NOT bLesenAlt THEN
  bAusPufferLesen:= TRUE;
END_IF;        
bLesenAlt:= bLesen;

// Kommando Puffer Initialisieren
IF bInit THEN
  bInPufferSchreiben:= FALSE;         // Gleichzeitig in Puffer schreiben wird ignoriert
  bAusPufferLesen:= FALSE;            // Gleichzeitig aus Puffer lesen wird ignoriert
  bPufferInit:= TRUE;
END_IF;

// Kommando Puffer fuellen
IF bFuellen THEN
  bInPufferSchreiben:= FALSE;         // Gleichzeitig in Puffer schreiben wird ignoriert
  bAusPufferLesen:= FALSE;            // Gleichzeitig aus Puffer lesen wird ignoriert
  bPufferFuellen:= TRUE;  
END_IF;

(********** Puffer Initialisieren/Füllen, Überlauf checken **********)
// Puffer Initialisieren
IF bPufferInit THEN
  FOR nI := 1 TO PG BY 1 DO
    anPuffer[nI]:= 0;    
  END_FOR;
  nAnzVorhDaten:= 0;  
  nZS:= 1;
  nZL:= 1;  
  bUeberlauf:= FALSE;
  bPufferInit:= FALSE;
END_IF;    

// Puffer füllen
IF bPufferFuellen THEN
  FOR nI := 1 TO PG BY 1 DO
    anPuffer[nI]:= nI;    
  END_FOR;
  nAnzVorhDaten:= PG;  
  nZS:= 1;
  nZL:= 1;    
  bUeberlauf:= FALSE;
  bPufferFuellen:= FALSE;
END_IF;  

// Schreiben Zeiger hat Ringgrenze erreicht    
IF nZS > PG THEN
  nZS:= 1;
END_IF;

// Lesen Zeiger hat Ringgrenze erreicht
IF nZL > PG THEN
  nZL := 1;
END_IF;

// Anzahl vorhandene Daten eingrenzen
IF nAnzVorhDaten > PG THEN
  nAnzVorhDaten:= PG;
ELSIF nAnzVorhDaten < 0 THEN
  nAnzVorhDaten:= 0;
END_IF;       

// Erkennung ob der Puffer voll ist und Lesen und Schreiben gleichzeitig ansteht
IF nAnzVorhDaten = PG AND bInPufferSchreiben AND bAusPufferLesen THEN
  GOTO Lesen;
  bVorrangLesen:= TRUE;      // dann muss erst gelesen und anschließend geschrieben werden (wegen unnötigem Überlauf)
ELSE
  bVorrangLesen:= FALSE;  
END_IF;    

(********************* In den Puffer schreiben **********************)
Schreiben:
  // Wert in Puffer schreiben
  IF bInPufferSchreiben THEN
    // Überlauf checken
    IF nAnzVorhDaten = PG THEN
      bUeberlauf:= TRUE;      // Überlauf wird lediglich signalisiert, neue Daten werden natürlich trozdem eingetragen
      nZL:= nZL + 1;          // Der Lesen Zeiger wird auf den nächsten gültigen Eintrag gesetzt
    ELSE
      bUeberlauf:= FALSE;
    END_IF;
    anPuffer[nZS]:= nIn;
    nZS:= nZS + 1;
    // Nur erhöhen wenn die Puffergrenze noch nicht erreicht ist (mehr passt ja nicht rein)  
    IF nAnzVorhDaten < PG THEN 
      nAnzVorhDaten:= nAnzVorhDaten + 1; 
    END_IF;  
    bInPufferSchreiben:= FALSE;
  END_IF;

  // Wenn Lesen Vorrang hatte dann wurde dies ja bereits erledigt
  IF bVorrangLesen THEN
    RETURN;       // also Ende hier
  END_IF;    

(*********************** Aus dem Puffer lesen ***********************)
Lesen:
  // Nur wenn Daten vorhanden sind, können Werte ausgelesen werden
  IF nAnzVorhDaten > 0 AND bAusPufferLesen THEN
    bUeberlauf:= FALSE;         // Sobald Daten wieder ausgelesen werden, bügeln wir das Überlaufbit wieder nieder
    nOut:= anPuffer[nZL];
    anPuffer[nZL]:= 0;          // Nachdem wir den Puffer ausgelesen haben, schreiben wir ne 0 rein 
    nZL:= nZL + 1;  
    nAnzVorhDaten:= nAnzVorhDaten - 1;  
    bAusPufferLesen:= FALSE;
  ELSIF nAnzVorhDaten = 0 AND bAusPufferLesen THEN    // Sind keine Daten vorhanden
    // nichts machen  
    bAusPufferLesen:= FALSE;
  END_IF;
  
  // Wenn Lesen Vorrang hatte  
  IF bVorrangLesen THEN
    GOTO Schreiben;             // dann muß ja noch geschrieben werden
  END_IF;    

END_FUNCTION_BLOCK
```
Gruß Didaddy


----------



## ohmbe (24 Oktober 2013)

Schau dir mal den FC 85 an vllt hilft dir das auch weiter

grüße 
ohmbe


----------

