Zykluszeit Teile/h

RON_87

Active member
Beiträge
36
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo zusammen,

Ich muss an einer Druckmaschine die Anzahl Teile pro Stunde berechnen die an einem Lichtgitter vorbeifahren.

Meine Vorgehensweise:
Zeit Start Teil1 am Lichtgitter
Zeit Stop Teil2 am Lichtgitter
Zykluszeit der CPU: 70 ms

Inwieweit spielt nun die Zykluszeit dabei eine Rolle ?
 

Ralle

Supermoderator
Teammitglied
Beiträge
15.101
Punkte Reaktionen
3.819
Im schlechtesten Fall ist deine errechnete Zeit 2*Zykluszeit ungenau, also hast du einen Fehler zwischen 0-140ms.
Allerdings hängt das auch von deinem Programm ab, etwas ungünstig geschrieben, (Reihenfolge der Auswertung in Code, Flankenauswertung etc.) könnte es z.Bsp. auch 2 Zykluszeiten dauern, bis du eine Zeit wirklich speicherst.
Mit Interrupteingängen kann man das umgehen.
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.148
Punkte Reaktionen
2.745
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo,
wenn deine Teile nicht zu klein sind, dass heißt der Impuls kleiner sein könnte wie deine Zykluszeit, dann spielt die dafür keine Rolle.
Du kannst, um die Teilezählung hochzurechnen, die Teile zählen, die innerhalb von einer Minute durchkommen und das dann hoch-multiplizieren. Je größer dein Zeitfenster umso genauer wird das Ganze - je kleiner umso ungenauer. Du kannst das natürlich dann zyklisch korrigieren bzw. an hand von schon vergangenen Zeitintervallen dann viel genauer werden ...

Gruß
Larry
 
OP
R

RON_87

Active member
Beiträge
36
Punkte Reaktionen
0
Es ist eine 416 CPU

Ich addiere zwischen Start und stop immer die aktuelle zykluszeit aus ob1 auf. Dann wird es auf die Stunde hochgerechnet. Vom s7 Programm passt es, denke ich.

Allerdings muss ich dies auch bei einer neu geplanten Maschine mathematisch nachweisen (ohne SPS Programm ). Habe sämtliche Werte:

Fördergeschwindigkeit
Einfahr bzw Ausfahrwege
Beschleunigung
Rampen usw.
Und genau hier liegt nun das Problem. wie wirkt nun die zykluszeit hier rein?
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.148
Punkte Reaktionen
2.745
... Ich addiere zwischen Start und stop immer die aktuelle zykluszeit aus ob1 auf. Dann wird es auf die Stunde hochgerechnet. Vom s7 Programm passt es, denke ich.

Wie du auf diese Weise allerdings auf Teile/Std. kommen willst ist mir unklar. Da würde mich die Formel doch mal sehr interessieren.
Auf diese Weise kannst du höchstens, wenn du die Fördergeschwindigkeit kennst, die Teile-Länge bestimmen ...

Gruß
Larry
 

borromeus

Well-known member
Beiträge
2.270
Punkte Reaktionen
329
Wenn Dir die Zykluszeit Kopfzerrechen macht (Du hast ja noch keine Angabe darüber gemacht in welcher Größenordnung (Teile/h) sich das abspielt), würde ich entweder mit einem AlarmOB arbeiten (Achtung: TPA aktivieren), oder eine DE-Baugruppe verwenden, die Alarme absetzt.
Was Deine Werte:

Fördergeschwindigkeit
Einfahr bzw Ausfahrwege
Beschleunigung
Rampen usw.

damit zu tun haben entzieht sich meinem Verständnis.

Ein Lichtschranke genügt doch.

Bei 70ms Zykluszeit bei einer 416er hast Du aber schon ordentlich viel Code getippselt.
;-)
 

Funky

Well-known member
Beiträge
155
Punkte Reaktionen
62
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo Larry,

anbei ein kleines Programm, wie man aus einem Taktimpuls auf die Produktionsrate kommt. Zu beachten ist das die Zykluszeit vom OB1 zu ungenau ist, da sie nur mit 1ms aufgelöst wird. Genauer ist es sie mit dem SFC64 auszulesen und zu berechnen. ZB. so:

CALL SFC 64
RET_VAL:= MD 508 //Temporärer Merker

L MD 508
L MD 504 //Zwischenspeicher Zykluszeit
-D
T MD 500 //Zykluszeit

L MD 508
T MD 504

Hier das Programm:

Code:
FUNCTION_BLOCK FB 850
TITLE =Produktionsrate
AUTHOR : HF
VERSION : 0.1

VAR_INPUT
  Taktimpuls : BOOL ; //Taktimpuls
  Reset : BOOL ; //Reset Produktionsrate
  Nr_DB_Speicher : INT ; //DB Nr von Speicher DB
  Zykluszeit : INT ; //Zykluszeit
END_VAR
VAR
  P_Rate : STRUCT  //Produktionsrate 
   _1_min : INT ; 
   _5_min : INT ; 
   _30_min : INT ; 
   _1_h : INT ; 
  END_STRUCT ; 
  P_Rate_gespeichert : STRUCT  //Produktionsrate gespeichert bei Auto Aus für Druck
   _1_min : INT ; 
   _5_min : INT ; 
   _30_min : INT ; 
   _1_h : INT ; 
  END_STRUCT ; 
  Z_P_Rate : STRUCT  //Zähler Produktionsrate 
   _1_min : INT ; 
   _5_min : INT ; 
   _30_min : INT ; 
   _1_h : INT ; 
  END_STRUCT ; 
  Summenzeit : STRUCT  //Summenzeit 
   _1_min : TIME ; 
   _5_min : TIME ; 
   _30_min : TIME ; 
   _1_h : TIME ; 
  END_STRUCT ; 
  Zeiger_Out : STRUCT  //Zeiger Speicher Wert auslesen
   _1_min : DINT ; 
   _5_min : DINT ; 
   _30_min : DINT ; 
   _1_h : DINT ; 
  END_STRUCT ; 
  Zeiger_In : DINT ; 
  Pausenzeit : TIME ; 
  M_Flanke_1 : BOOL ; //Flankenmerker
  M_Flanke_2 : BOOL ; //Flankenmerker
END_VAR
VAR_TEMP
  Fehlercod : INT ; //Fehlercode Blockmove 
  Nr_DB : WORD ; //Nr. Speicherbaustein
  MW_Temp : WORD ; //Zwischenmerker
  Z_Merker : BOOL ; //Zwischenmerker
END_VAR
BEGIN
NETWORK
TITLE =Datenbaustein erzeugen
      L     #Nr_DB_Speicher; //Int wandeln in Word
      T     #Nr_DB; 
      CALL SFC   24 (//Test Speicher-DB schon vorhanden 
           DB_NUMBER                := #Nr_DB,//Nr. DBxx
           RET_VAL                  := #Fehlercod,
           DB_LENGTH                := #MW_Temp,
           WRITE_PROT               := #Z_Merker);
      L     #Fehlercod; //W#16#80B1 Der DB mit der angegebenen Nummer ist auf der CPU nicht vorhanden
      L     W#16#80B1; 
      ==I   ; 
      SPBN  DBda; 
// neuen Datenbaustein erzuegen
      CALL SFC   22 (
           LOW_LIMIT                := #Nr_DB,//erste Nr. DBxx
           UP_LIMIT                 := #Nr_DB,//letzte Nr. DBxx
           COUNT                    := W#16#FFFE,//65534 Byte
           RET_VAL                  := #Fehlercod,
           DB_NUMBER                := #MW_Temp);
      SET   ; 
      S     #Reset; 
DBda: NOP   0; 
NETWORK
TITLE =Bei Reset alle Werte Nullen
      U     #Reset; 
      SPBN  noNe; 
      R     #Reset; 
      L     L#0; 
      T     #Z_P_Rate._1_min; 
      T     #Z_P_Rate._5_min; 
      T     #Z_P_Rate._30_min; 
      T     #Z_P_Rate._1_h; 
      T     #Summenzeit._1_min; 
      T     #Summenzeit._5_min; 
      T     #Summenzeit._30_min; 
      T     #Summenzeit._1_h; 
      T     #Zeiger_Out._1_min; 
      T     #Zeiger_Out._5_min; 
      T     #Zeiger_Out._30_min; 
      T     #Zeiger_Out._1_h; 
      T     #Pausenzeit; 
      T     #Zeiger_In; 
noNe: NOP   0; 
NETWORK
TITLE =Bei Auto-Aus Produktionrate speichern (für Print)
      U     M     10.0; 
      FN    #M_Flanke_2; 
      SPBN  auto; 
      CALL SFC   20 (
           SRCBLK                   := #P_Rate,
           RET_VAL                  := #Fehlercod,
           DSTBLK                   := #P_Rate_gespeichert);
auto: NOP   0; 
NETWORK
TITLE =Pausenzeit aus Zykluszeit
      L     #Pausenzeit; 
      L     #Zykluszeit; 
      +D    ; 
      T     #Pausenzeit; 
NETWORK
TITLE =DB öffnen
      AUF   DB [#Nr_DB]; //Speicher Produktionsrate
NETWORK
TITLE =Bei Taktimpuls neue Zeit in Zeitspeicher
      U     #Taktimpuls; 
      FP    #M_Flanke_1; 
      SPBN  noSr; 
      L     #Zeiger_In; //Zeiger Schreibposition
      SLD   5; //4 Byte
      LAR1  ; //Achtung +AR1 geht nur bis p#4095.7
      L     #Pausenzeit; 
      T     DBD [AR1,P#0.0]; //Zeit in Zeitspeicher
// 1 min
      L     #Summenzeit._1_min; //Summenzeit = Pausenzeit + Summenzeit
      +D    ; 
      T     #Summenzeit._1_min; 
      L     #Z_P_Rate._1_min; //Produktionsrate erhöhen
      +     1; 
      T     #Z_P_Rate._1_min; 
// 5 min
      L     #Pausenzeit; 
      L     #Summenzeit._5_min; 
      +D    ; 
      T     #Summenzeit._5_min; 
      L     #Z_P_Rate._5_min; 
      +     1; 
      T     #Z_P_Rate._5_min; 
// 30 min
      L     #Pausenzeit; 
      L     #Summenzeit._30_min; 
      +D    ; 
      T     #Summenzeit._30_min; 
      L     #Z_P_Rate._30_min; 
      +     1; 
      T     #Z_P_Rate._30_min; 
// 1 h
      L     #Pausenzeit; 
      L     #Summenzeit._1_h; 
      +D    ; 
      T     #Summenzeit._1_h; 
      L     #Z_P_Rate._1_h; 
      +     1; 
      T     #Z_P_Rate._1_h; 
// Pausenzeit löschen
      L     L#0; //Pausenzeit nach Eintrag löschen
      T     #Pausenzeit; 
// Zeiger stellen
      L     #Zeiger_In; //Zeiger Schreibposition erhöhen
      +     1; 
      T     #Zeiger_In; 
      L     L#16383; //max.Grösse Summenspeicher
      <D    ; 
      SPB   noSr; 
      L     L#0; //Zeiger auf Anfang
      T     #Zeiger_In; 
noSr: NOP   0; 
NETWORK
TITLE =Produktionsrate berechnen  1 min
N_1m: L     #Zeiger_Out._1_min; //Kontrolle Zeiger
      L     #Zeiger_In; 
      ==D   ; 
      SPB   E_1m; 
      L     #Pausenzeit; 
      L     #Summenzeit._1_min; //Summenzeit
      +D    ; 
      L     L#60000; //Abfragezeit in ms
      <D    ; 
      SPB   E_1m; 
      L     #Zeiger_Out._1_min; //Zeiger Leseposition
      SLD   5; //4 Byte
      LAR1  ; //Achtung +AR1 geht nur bis p#4095.7
      L     #Summenzeit._1_min; 
      L     DBD [AR1,P#0.0]; //Zeit aus Zeitspeicher
      -D    ; 
      T     #Summenzeit._1_min; 
      L     #Z_P_Rate._1_min; //Produktionsrate erhöhen
      +     -1; 
      T     #Z_P_Rate._1_min; 
      L     #Zeiger_Out._1_min; //Zeiger Leseposition erhöhen
      +     1; 
      T     #Zeiger_Out._1_min; 
      L     L#16383; //max.Grösse Summenspeicher
      <D    ; 
      SPB   N_1m; 
      L     L#0; //Zeiger auf Anfang
      T     #Zeiger_Out._1_min; 
E_1m: L     #Z_P_Rate._1_min; //Anzahl Zeiten im Messbereich
      T     #P_Rate._1_min; //xxx Teile/min
NETWORK
TITLE =Produktionsrate berechnen  5 min
N_5m: L     #Zeiger_Out._5_min; 
      L     #Zeiger_In; 
      ==D   ; 
      SPB   E_5m; 
      L     #Pausenzeit; 
      L     #Summenzeit._5_min; 
      +D    ; 
      L     L#300000; //Abfragezeit in ms
      <D    ; 
      SPB   E_5m; 
      L     #Zeiger_Out._5_min; 
      SLD   5; 
      LAR1  ; 
      L     #Summenzeit._5_min; 
      L     DBD [AR1,P#0.0]; 
      -D    ; 
      T     #Summenzeit._5_min; 
      L     #Z_P_Rate._5_min; 
      +     -1; 
      T     #Z_P_Rate._5_min; 
      L     #Zeiger_Out._5_min; 
      +     1; 
      T     #Zeiger_Out._5_min; 
      L     L#16383; 
      <D    ; 
      SPB   N_5m; 
      L     L#0; 
      T     #Zeiger_Out._5_min; 
E_5m: L     #Z_P_Rate._5_min; 
      L     10; 
      *I    ; 
      L     5; 
      /I    ; 
      T     #P_Rate._5_min; //xxx Teile/min
NETWORK
TITLE =Produktionsrate berechnen  30 min
N30m: L     #Zeiger_Out._30_min; 
      L     #Zeiger_In; 
      ==D   ; 
      SPB   E30m; 
      L     #Pausenzeit; 
      L     #Summenzeit._30_min; 
      +D    ; 
      L     L#1800000; //Abfragezeit in ms
      <D    ; 
      SPB   E30m; 
      L     #Zeiger_Out._30_min; 
      SLD   5; 
      LAR1  ; 
      L     #Summenzeit._30_min; 
      L     DBD [AR1,P#0.0]; 
      -D    ; 
      T     #Summenzeit._30_min; 
      L     #Z_P_Rate._30_min; 
      +     -1; 
      T     #Z_P_Rate._30_min; 
      L     #Zeiger_Out._30_min; 
      +     1; 
      T     #Zeiger_Out._30_min; 
      L     L#16383; 
      <D    ; 
      SPB   N30m; 
      L     L#0; 
      T     #Zeiger_Out._30_min; 
E30m: L     #Z_P_Rate._30_min; 
      L     3; 
      /I    ; 
      T     #P_Rate._30_min; //xxx,x Teile/min
NETWORK
TITLE =Produktionsrate berechnen  1 h
N_1h: L     #Zeiger_Out._1_h; 
      L     #Zeiger_In; 
      ==D   ; 
      SPB   E_1h; 
      L     #Pausenzeit; 
      L     #Summenzeit._1_h; 
      +D    ; 
      L     L#3600000; 
      <D    ; 
      SPB   E_1h; 
      L     #Zeiger_Out._1_h; 
      SLD   5; 
      LAR1  ; 
      L     #Summenzeit._1_h; 
      L     DBD [AR1,P#0.0]; 
      -D    ; 
      T     #Summenzeit._1_h; 
      L     #Z_P_Rate._1_h; 
      +     -1; 
      T     #Z_P_Rate._1_h; 
      L     #Zeiger_Out._1_h; 
      +     1; 
      T     #Zeiger_Out._1_h; 
      L     L#16383; 
      <D    ; 
      SPB   N_1h; 
      L     L#0; 
      T     #Zeiger_Out._1_h; 
E_1h: L     #Z_P_Rate._1_h; 
      L     6; 
      /I    ; 
      T     #P_Rate._1_h; //xxx,x Teile/min
END_FUNCTION_BLOCK

Am FB kann die Lichtschranke am Takteingang angeschlossen werden. Weiterhin wird die Zykluszeit (MD500) benötigt sowie ein freier DB. Dieser DB wird automatisch vom Programm erzeugt. Das hat den Vorteil dass er nur Arbeitsspeicher und kein Ladespeicher benötigt (64KByt).

Die Messwerte (Produktionsrate) liegen bei mir im statischen Bereich. Ich greife vom Pult direkt darauf zu.
Hier ein Bild von der Visualisierung. In diesen Bild wird das Programm zweimal benutzt (Brutto & Netto).

P_Rate.jpg

Gruss Harald
 

Thomas_v2.1

Well-known member
Beiträge
8.800
Punkte Reaktionen
2.697
Harald, ich rätsel gerade über dein Programm.
Sehe ich das richtig dass die Intervallwerte auch nur im Intervall berechnet werden und nicht kontinuierlich? Die naheliegendste Lösung wäre doch die Stücke in einer Minute (das kleinste Intervall) zu zählen und die Werte minütlich in einen Ringspeicher mit 60 Werten zu schreiben, oder einfach drei weitere Gesamtzähler für 5, 30 und 60 Minuten aufbauen. Ich seh grad nicht wozu das Brimborium mit dem riesen DB da ist.
 

Funky

Well-known member
Beiträge
155
Punkte Reaktionen
62
Hallo Thomas,

das Programm berechnet die Produktionsrate kontinuierlich. Es hat den Vorteil das es auch bei sehr unzyklischen Taktraten einwandfrei Funktioniert.
In einer größeren Version kann es Produktionsraten bis zu 8 h bei einem Eingangstakt von größeren 1,7 Sekunden berechnen.

Die Auswertung läuft wie folgt ab:
  • Bei jeden Takt wird die Differenz zum vorherigen Takt (Pausenzeit) in den Ringpuffer geschrieben NW6
  • weiterhin wird die Pausenzeit auf den Summenspeicher für jedes Messintervall summiert, und der Zähler der Produktionsrate erhöht
  • in der Auswertung (ab NW7) wird in jeden Zyklus kontrolliert, ob der Summenspeicher plus der aktuellen Pausenzeit grösser ist als das Messintervall. Ist dies der Fall wird der älteste Wert aus den Summenspeicher abgezogen und der Zähler der Produktionsrate verringert.
  • dieser Zähler zeigt die Produktionsrate an
  • der Rest dient nur zum stellen der Zeiger für den Ringpuffer
Das Prinzip hat den Vorteil dass eine sehr genaue Anzeige der Produktionsratte auch über große Messzeiten und sehr unkontrollierten Betrieb möglich ist.

Gruß Harald
 

Thomas_v2.1

Well-known member
Beiträge
8.800
Punkte Reaktionen
2.697
Zuviel Werbung?
->Hier kostenlos registrieren
Ah, Ok.
Meine Denkweise wäre eher die Stückzahlen in einem festen Intervall (z.B. pro Sekunde) in einem Ringspeicher mit 60*60 Werten für eine Stunde abzulegen und dann die verschiedenen Intervallzeiger darauf loszulassen. Viel schneller als 1s kommt die Visu auch nicht hinterher.
Aber viele Wege führen nach Rom.
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.148
Punkte Reaktionen
2.745
Ich muss gestehen, dass mein Ansatz so wie der von Thomas ist / wäre ...
Wenn man mit einem aufsummierenden Ringspeicher arbeitet wäre hier die mögliche Ungenauigkeit m.E. eher marginal ...

Gruß
Larry
 

Andi_F

New member
Beiträge
2
Punkte Reaktionen
0
Es ist eine 416 CPU

Allerdings muss ich dies auch bei einer neu geplanten Maschine mathematisch nachweisen (ohne SPS Programm ). Habe sämtliche Werte:

Fördergeschwindigkeit
Einfahr bzw Ausfahrwege
Beschleunigung
Rampen usw.
Und genau hier liegt nun das Problem. wie wirkt nun die zykluszeit hier rein?


Hallo,


um dein Zählen richtig zu gestalten, stimme ich den anderen bei. Die beste (richtige) Lösung ist aufsummieren und hochrechnen. Wie schon geschrieben: Je größer das Zeitintervall, desto genauer.


Zu dem mathematischen Nachweis:
Willst du eine Anlagenleistung berechnen oder nachweisen, dass deine Steuerung die Teile zählen und auf Stk./h berechnen kann?
- Um die Leistung zu berechnen, benötigst du den zeitlichen Ablauf deiner Anlage und Fördergeschwindigkeiten.
- Für das Berechnen der Teile pro Stunde, benötigst du einfach eine CPU, welche deine Sensoren in Abhängigkeit von den Schaltintervallen (Teilegröße, Abstand, Fördergeschwindigkeit) verarbeiten kann. Danach kommt wieder das
Aufsummieren und hochrechnen an die Reihe.

lg
 
Oben