# Bitte um Feedback



## xvitali (18 September 2008)

Hallo,
da ich fiel von diesem Forum gelernt habe will ich meine Code zum Kritik hinstellen. 
Was muss ich noch verbessern? Das Programm habe ich getestet und Funktioniert 
Für jede Anregung bin ich Dankbar


```
//Belade durch MSST EIN und AUS schalten

      U     #Belade_An; 
      S     #LED_Belade_AN; 
      R     #LED_Belade_AUS; 
      U     #Belade_Aus; 
      R     #LED_Belade_AN; 
      S     #LED_Belade_AUS; 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//-----     MDA oder AUTOMATIK zwei verschiedene Betriebsarten                      -
//-----------------------------------------------------------------------------------
      O     #Automatik; // Nur in der endsprechender Betriebsart sollte
      O     #MDA; // die Schritkette gestartet werden
      =     #AUTOorMDA; 

      U     #MDA; 
      U     #Takten; 
      O     ; 
      U     #Automatik; 
      =     #SK_Takten; 

NETWORK
TITLE =Schritkette

// -->- Startbedingung für Schrittkette
      U     #IO_Start; 
      S     #start; 
      O     #Bel_Reset; 
      O     #start; 
      SPB   STA1; 
      L     0; 
      T     #Schrittnummer; 
STA1: NOP   0; 
      O     #Bel_Reset; 
      =     #LED_belade_Reset; 
      R     #Start_laufzt1; 

//----   Laufzeit wird im Programm geändert ------------------------------->
      CALL #laufz1 (
           IN                       := #Start_laufzt1,
           PT                       := #akt_zeit,
           Q                        := #Laufzt_ok);
//----  Überwachung von Schritdauer --------------------------------------->
      CALL #laufz2 (
           IN                       := #Start_laufzt1,
           PT                       := T#10S,
           Q                        := #Zeitueberschr);
//-------------------------------------------------------------------------------------------
      L     #Schrittnummer; 
      SPL   SKED; 
      SPA   S00; // Initialisierung
      SPA   S01; // Einlesesperre setzen
      SPA   S02; // BeladeZylinder vorschieben Teil Beladen
      SPA   S03; // Teil spannen in spannzange
      SPA   S04; // BeladeZylinder zurückfahren in die Ausgangsposition
      SPA   S05; // Positionierzylinder zur Teile holen
      SPA   S06; // Positionerer Teile positioneren
      SPA   S07; // End
SKED: SPA   END1; 

//------------------------------------------------------------------
S00:  NOP   0; // Initialisierung
      U     #Druckluft_vor; // Wenn keine Druckluft Zylinder nicht schalten
      U     #Steuerung_An; 
      SPBN  nvor; 
      SET   ; 
      R     #Beladezyl; 
      U     #Beladezyl_hinten; 
      S     #Pos_zyl_hoch; 
      R     #Pos_zyl_runter; 
      SPA   vor; 
nvor: NOP   0; 
      SET   ; 
      =     #F_Druckluft; 
      R     #Beladezyl; 
      R     #Pos_zyl_hoch; 
      R     #Pos_zyl_runter; 

vor:  U     #Beladezyl_hinten; 
      U     #Pos_zyl_oben; 
      U     #start; 
      U     #Steuerung_An; 
      U     #AUTOorMDA; 
      U     #LED_Belade_AN; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
//-------------------------------------------------------------------- 
S01:  NOP   0; // Einlesesperre setzen
      SET   ; 
      S     #Einlesespere; 
      =     #Spannz_Auf; 
      S     #Start_laufzt1; 
      UN    #TeilinSpannz; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
//--------------------------------------------------------------------
S02:  NOP   0; // BeladeZylinder vorschieben Teil Beladen
      LAR1  P##akt_zeit; 
      L     T#1S; 
      T     D [AR1,P#0.0]; 
      SET   ; 
      S     #Beladezyl; 
      S     #Start_laufzt1; 
      R     #Spannz_Auf; 

      U     #Beladezyl_vorne; 
      U     #Laufzt_ok; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
//--------------------------------------------------------------------
S03:  NOP   0; // Teil spannen in spannzange
      LAR1  P##akt_zeit; 
      L     T#2S; 
      T     D [AR1,P#0.0]; 
      SET   ; 
      =     #Spannz_Zu; 
      S     #Start_laufzt1; 

      U     #TeilinSpannz; 
      U     #Laufzt_ok; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
//--------------------------------------------------------------------
S04:  NOP   0; // BeladeZylinder zurückfahren in die Ausgangsposition
      LAR1  P##akt_zeit; 
      L     T#1S500MS; 
      T     D [AR1,P#0.0]; 
      SET   ; 
      R     #Spannz_Zu; 
      R     #Einlesespere; 
      R     #Beladezyl; 
      S     #Start_laufzt1; 

      U     #Beladezyl_hinten; 
      U     #Laufzt_ok; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 

//--------------------------------------------------------------------
S05:  NOP   0; // Positionierzylinder zur Teile holen
      LAR1  P##akt_zeit; 
      L     T#5S; 
      T     D [AR1,P#0.0]; 
      SET   ; 
      R     #Pos_zyl_hoch; 
      S     #Pos_zyl_runter; 
      S     #Start_laufzt1; 

      U     #Pos_zyl_unten; 
      U     #Laufzt_ok; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
//-------------------------------------------------------------------
S06:  NOP   0; // Positionerer Teile positioneren
      LAR1  P##akt_zeit; 
      L     T#5S; 
      T     D [AR1,P#0.0]; 
      SET   ; 
      S     #Pos_zyl_hoch; 
      R     #Pos_zyl_runter; 
      S     #Start_laufzt1; 

      U     #Pos_zyl_oben; 
      U     #Laufzt_ok; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
//--------------------------------------------------------------------
S07:  NOP   0; 
      SET   ; 
      R     #start; 
      U     #SK_Takten; 
      S     #SK_Weiter; 
      SPA   END1; 
END1: NOP   0; 

//  Weiterschalten
      U     #SK_Weiter; 
      SPBN  SKWE; 
      L     #Schrittnummer; 
      +     1; 
      T     #Schrittnummer; 
      SET   ; 
      R     #SK_Weiter; 
      R     #Start_laufzt1; 
SKWE: NOP   0; 



NETWORK
TITLE =Fehlermeldungen für Belade

      AUF   DB     2; 
      U     #Zeitueberschr; 
      SPBN  END2; 

      L     #Schrittnummer; 
      SPL   FMED; 
      SPA   F00; 
      SPA   F01; 
      SPA   F02; 
      SPA   F03; 
      SPA   F04; 
      SPA   F05; 
      SPA   F06; 
      SPA   F07; 
FMED: SPA   END2; 
//-->------------------------------------------------------------------
F00:  NOP   0; 

      SPA   END2; 
//-->------------------------------------------------------------------ 
F01:  NOP   0; // 700200 0 0 "BELADE ROHTEILEZUFUHRZYLINDER LAUFZEITFEHLER "
      SET   ; 
      =     DBX  196.0; 
      SPA   END2; 
//-->------------------------------------------------------------------
F02:  NOP   0; // 700201 0 0 "BELADE ROHTEILEZUFUHRZYLINDER LAUFZEITFEHLER "
      SET   ; 
      S     DBX  196.1; 
      SPA   END2; 
//-->------------------------------------------------------------------
F03:  NOP   0; // 700202 0 0 "ROHTEIL SPANNEN LAUFZEITFEHLER"
      SET   ; 
      S     DBX  196.2; 
      SPA   END2; 
//-->------------------------------------------------------------------
F04:  NOP   0; // 700203 0 0 "BELADE ROHTEILEZUFUHRZYLINDER LAUFZEITFEHLER"
      SET   ; 
      S     DBX  196.3; 
      SPA   END2; 
//-->------------------------------------------------------------------
F05:  NOP   0; // 700204 0 0 "BELADE HUBZYLINDER LAUFZEITFEHLER"
      SET   ; 
      S     DBX  196.4; 
      SPA   END2; 
//-->------------------------------------------------------------------
F06:  NOP   0; // 700205 0 0 "BELADE HUBZYLINDER LAUFZEITFEHLER"
      S     DBX  196.5; 
      SPA   END2; 
//-->------------------------------------------------------------------
F07:  NOP   0; 
      SPA   END2; 
//-->------------------------------------------------------------------
END2: NOP   0; 
      U     #Reset; 
      R     DBX  196.0; 
      R     DBX  196.1; 
      R     DBX  196.2; 
      R     DBX  196.3; 
      R     DBX  196.4; 
      R     DBX  196.5; 
      R     DBX  196.6; 
      R     DBX  196.7; 
      U     #Bel_Reset; 
      R     #start; 

END_FUNCTION_BLOCK
```
__________________________________________________________________

Lieber von den Richtigen kritisiert als von den Falschen gelobt werden." - _Gerhard Kocher_


----------



## johnij (18 September 2008)

XXXXXXXXXXx
xxxxxxxxxxxxxxxxx


Bitte Beitrag löschen


----------



## Rainer Hönle (18 September 2008)

johnij schrieb:


> Hier wir entweder zu SKED oder zu S00 gesprungen.
> S01...... werden nicht berücksichtigt


Habe jetzt die Logik nicht nachvollzogen, aber rein anweisungsmäßig ist der Code korrekt und der Sprung erfolgt in Abhängigkeit von der Schrittnummer. 
Wo steckt das Problem bzw. die Unkorrektheit?


----------



## vierlagig (18 September 2008)

johnij schrieb:


> Hier wir entweder zu SKED oder zu S00 gesprungen.
> S01...... werden nicht berücksichtigt



das ist falsch, schau dir den befehl SPL - Sprungleiste nochmal genauer an, findest du im AWL-handbuch kapitel 6.3. ... keine zeit zu haben rechtfertigt nicht, falsche antworten zu geben


----------



## johnij (18 September 2008)

vierlagig schrieb:


> das ist falsch, schau dir den befehl SPL - Sprungleiste nochmal genauer an, findest du im AWL-handbuch kapitel 6.3. ... keine zeit zu haben rechtfertigt nicht, falsche antworten zu geben


 

@4L
Ich gebe  dir recht...sorry


----------



## xvitali (18 September 2008)

> Wo steckt das Problem bzw. die Unkorrektheit?


Also die Schrittkette habe ich getestet an der Maschine und die funktioniert. Da ich in dem Betrieb alleine bin der Programmiert wollte ich nur eure Meinug hören und Anregungen. Was man so besser machen kann


----------



## vierlagig (18 September 2008)

xvitali schrieb:


> Was man so besser machen kann



die fehlermeldungen find ich so nicht gut gelöst. bis dahin hast du alles so programmiert, dass der baustein durchaus mehrfach aufgerufen werden kann (bis auf die schrittüberwachungszeit, aber das find ich erstmal nicht so tragisch) und plötzlich fängst du an global zu adressieren ... nö, das ist nicht schön!

@johnij: das x-en deines beitrags bringt auch nix, ich hab dich zitiert, mach ich immer, seit ich weiß, dass du x-t


----------



## xvitali (18 September 2008)

> und plötzlich fängst du an global zu adressieren ... nö, das ist nicht schön!



soll ich den DB NR übergeben an FB schnitstelle oder Fehler Rücksetzen sollte anderes sein?


----------



## vierlagig (18 September 2008)

wenn das alles in einen alarm-db geht würd ich die nummer übergeben, ja, und einen offset, der die startadresse angibt, von der aus die 8 fehlerbits aus, indirekt adressiert werden.

ansonsten: bau die das fehlerbyte zusammen, schreib es auf einen out und dann kannst du es von da aus direkt in einen DB deiner wahl oder einen anderen speicherbereich schreiben


----------



## xvitali (19 September 2008)

Ich habe jetzt die fehlermeldungen so abgeändert aber der vorteil ist mir nicht einleuchtend


```
L     #Fehler_DB
      T     #dbnr
      AUF   DB [#dbnr]

      LAR1  P#DBX 196.0

      U     #Zeitueberschr
      SPBN  END2
      L     #Schrittnummer
      SPL   FMED
      SPA   F00
      SPA   F01
      SPA   F02
      SPA   F03
      SPA   F04
      SPA   F05
      SPA   F06
      SPA   F07
FMED: SPA   END2
//-->------------------------------------------------------------------
F00:  NOP   0

      SPA   END2
//-->------------------------------------------------------------------ 
F01:  NOP   0                           // 700200 0 0 "BELADE ROHTEILEZUFUHRZYLINDER LAUFZEITFEHLER "
      SET   
      =     DBX [AR1,P#0.2]
      SPA   END2
//-->------------------------------------------------------------------
F02:  NOP   0                           // 700201 0 0 "BELADE ROHTEILEZUFUHRZYLINDER LAUFZEITFEHLER "
      SET   
      S     DBX [AR1,P#0.3]
      SPA   END2
//-->------------------------------------------------------------------
F03:  NOP   0                           // 700202 0 0 "ROHTEIL SPANNEN LAUFZEITFEHLER"
      SET   
      S     DBX [AR1,P#0.4]
      SPA   END2
//-->------------------------------------------------------------------
F04:  NOP   0                           // 700203 0 0 "BELADE ROHTEILEZUFUHRZYLINDER LAUFZEITFEHLER"
      SET   
      S     DBX [AR1,P#0.5]
      SPA   END2
//-->------------------------------------------------------------------
F05:  NOP   0                           // 700204 0 0 "BELADE HUBZYLINDER LAUFZEITFEHLER"
      SET   
      S     DBX [AR1,P#0.6]
      SPA   END2
//-->------------------------------------------------------------------
F06:  NOP   0                           // 700205 0 0 "BELADE HUBZYLINDER LAUFZEITFEHLER"
      S     DBX [AR1,P#0.7]
      SPA   END2
//-->------------------------------------------------------------------
F07:  NOP   0
      SPA   END2
//-->------------------------------------------------------------------
END2: NOP   0
      U     #Reset
      R     DBX [AR1,P#0.0]
      R     DBX [AR1,P#0.1]
      R     DBX [AR1,P#0.2]
      R     DBX [AR1,P#0.3]
      R     DBX [AR1,P#0.4]
      R     DBX [AR1,P#0.5]
      R     DBX [AR1,P#0.6]
      R     DBX [AR1,P#0.7]
      U     #Bel_Reset
      R     #start
```


----------



## vierlagig (19 September 2008)

xvitali schrieb:


> Ich habe jetzt die fehlermeldungen so abgeändert aber der vorteil ist mir nicht einleuchtend



wenn du das 
LAR1  P#DBX 196.0

jetzt noch variabel gestaltest, kannst du deine schrittkette inkl. feherauswertung in deine bibliothek schmeißen und immer rausholen, wenn du sie brauchst, ohne auf die schon verwendeten adressen und datenbausteine achten zu müssen ... verstehste?


----------



## xvitali (19 September 2008)

Ok das habe ich verstanden! 

Dann kann ich auch ein FC Baustein Fehlerauswertung schreiben und für andere schrittketten verwenden. Nur DB Nummer, Schrittnummer und Offset übergeben.


```
L     #Fehler_DB
      T     #dbnr
      AUF   DB [#dbnr]
      L     #DB_FL_offset
      SLD   3
      LAR1
```


----------



## vierlagig (19 September 2008)

xvitali schrieb:


> Ok das habe ich verstanden!
> 
> Dann kann ich auch ein FC Baustein Fehlerauswertung schreiben und für andere schrittketten verwenden. Nur DB Nummer, Schrittnummer und Offset übergeben.



ja, oder so ... mußt halt sehen, welche struktur sinnvoll ist, wenn du 20 unterschiedliche schrittketten, mit selber fehlerauswertung hast, macht der FC sinn, wenn du 20 gleiche schrittketten mit der selben fehlerauswertung hast, die variante vom anfang ...


----------



## kiestumpe (19 September 2008)

*Ein oder vielfachverwendung?*

BTW: wie oft soll der Baustein aufgerufen werden? 
Währe, gerade wenn du die Schrittkette von der Time-Out und Fehlerüberwachung trennst evt ein FB nicht die bessere Wahl?
Kannst du uns mal die Schnittstellen noch zeigen (IN/OUT usw.)


----------



## xvitali (19 September 2008)

Der Baustein wird nur einmal aufgerufen


```
FUNCTION_BLOCK FB 110
TITLE =Belade für Rohteile 
{ S7_language := '9(1) Englisch (USA)  18.09.2008  14:54:05' }
VERSION : 0.1


VAR_INPUT
  Belade_An : BOOL ;    
  Belade_Aus : BOOL  := TRUE;    
  Takten : BOOL ;    
  IO_Start : BOOL ;    
  Steuerung_An : BOOL ;    
  Automatik : BOOL ;    
  MDA : BOOL ;    
  Beladezyl_vorne : BOOL ;    
  Beladezyl_hinten : BOOL ;    
  Pos_zyl_oben : BOOL ;    
  Pos_zyl_unten : BOOL ;    
  Teilvorh : BOOL ;    
  TeilinSpannz : BOOL ;    //Teil in Spannzange gespannt
  Druckluft_vor : BOOL ;    
  Bel_Reset : BOOL ;    
  Reset : BOOL ;    
  Fehler_DB : INT ;    
  DB_FL_offset : INT ;    
END_VAR
VAR_OUTPUT
  Schrittnummer : INT ;    
  Beladezyl : BOOL ;    
  Pos_zyl_hoch : BOOL ;    
  Pos_zyl_runter : BOOL ;    
  Foerderband : BOOL ;    
  Stuffenfoer : BOOL ;    
  Einlesespere : BOOL ;    
  Spannz_Zu : BOOL ;    //Spannzange zu
  Spannz_Auf : BOOL ;    
  LED_Belade_AN : BOOL ;    
  LED_Belade_AUS : BOOL ;    
  LED_belade_Reset : BOOL ;    
END_VAR
VAR
  laufz1 : SFB 4;    //Laufzeitüberwachung
  laufz2 : SFB 4;    //Laufzeitüberwachung für jeden einzelnen Schritt feste zeit
  laufz3 : SFB 4;    //Zylinder überwachung 
  laufz4 : SFB 4;    //Zylinder überwachung 
  SK_Weiter : BOOL ;    
  Start_laufzt1 : BOOL ;    
  Laufzt_ok : BOOL ;    
  akt_zeit : TIME ;    
  start : BOOL ;    
  Zeit_Ein : BOOL ;    
  Zeit_Ein2 : BOOL ;    
  Zeitueberschr : BOOL ;    //Zeitüberschritten Fehler ausgeben
END_VAR
VAR_TEMP
  AUTOorMDA : BOOL ;    
  SK_Takten : BOOL ;    
  Laufzeitfehler : BOOL ;    
  Laufzeitfehler2 : BOOL ;    
  F_Druckluft : BOOL ;    //Fehler Druckluft nicht vorhanden
  flanke1 : BOOL ;    
  dbnr : INT ;    
END_VAR
```


----------



## kiestumpe (19 September 2008)

Die nichtverwendeten Variablen solltest du löschen.

Warum hantierst du bei #akt_Time in deinem Programm mit Pointern?


----------



## xvitali (19 September 2008)

Warum pointer? Weil ich verschiedene zeiten brauche. Der Positionier Zylinder braucht mehr zeit als der Beladezylinder oder Spannzange schliessen ist wieder eine andere Zeit. 

Kann man das auch anderes lössen?


----------



## kiestumpe (19 September 2008)

yep, du kannst soviele Timer in deinem FB instanziieren, wie du benötigst.
Warum hast du z.B. Laufz1, laufz2 usw.?


----------



## xvitali (19 September 2008)

Ja das ist kleine schrittkette wenn ich aber mit 20 oder 30 schritten habe, soll ich dann für jeden Schritt einen Teimer in FB instnzieren?


----------



## kiestumpe (19 September 2008)

Warum nicht? natürlich nur für die Zeitschritte. 
Normalerweise ist ja nicht in jedem Schritt ein Zeitglied enthalten sondern andere Bedingungen.

Als Alternative, wenn die Zeiten nicht super-genau sein müssen, reicht auch sowas wie nen Flanken-Zähler-FC, da reicht dann je ne Zählvariable in Verbindung mit dem Taktmerker - 
(Glaub es mir, du wirst es mir danken, wenn du den Baustein in 3 Jahren mal wieder anfassen musst.)

hth


----------



## xvitali (19 September 2008)

kiestumpe schrieb:


> Als Alternative, wenn die Zeiten nicht super-genau sein müssen, reicht auch sowas wie nen Flanken-Zähler-FC, da reicht dann je ne Zählvariable in Verbindung mit dem Taktmerker -
> hth



Flanken-Zähler-FC?  Kenne ich nicht.


----------



## vierlagig (19 September 2008)

xvitali schrieb:


> Flanken-Zähler-FC?  Kenne ich nicht.



so, da kommt der vierer wieder ins spiel:

taktmerkerbyte kennste aber, oder? es gibt die möglichkeit cpu-weit 8 taktmerker von 0,1s bis 2s zu definieren (HW-konfig - > CPU-eigenschaften)

mit:


```
*
      U     #PLC_PULSE
      FP    #HELP_FLAG
      SPBN  _001
      L     #TIMER_MW
      +     1
      T     #TIMER_MW
_001: NOP   0
```

kannst du einen beliebigen takt hochzählen lassen, wobei jeweils die positive flanke zählt. jetzt nur noch auf einen bestimmten wert vergleichen, aktion ausführen und den timerwert auf 0 setzen und schon zählt er von vorn ...

da du eine relativ genaue zeit haben wollen, empfehl ich dir den 0,1s-takt, also Mx.0, aber nicht global sondern an der bausteinschnittstelle übergeben, sonst verlierst du die harterarbeitete bibliotheksfähigkeit bald wieder...


----------

