# Timertrick: Zeit Messen, Anhalten, Weiterlaufen lassen,..



## Hartmut Lux (25 August 2007)

Hallo Leute, ich bin auf einen kleinen Trick für Zusatztimer gestoßen:

CPU-Zykluszeit messen und im DINT aufsummieren ergibt einen ms-DINT Wert (entspricht IEC-Format, bis zu 23Tage!). 

Auf diese Weise kann man Zeiten einfach messen und die Messung beliebig  anhalten und weiterlaufen lassen. Der letzte Zeitwert übersteht auch einen Steuerspannungsausfall (Timer mach da weiter wo CPU vor Spannungsausfall stand).

Habe mir so eine Funktion für 100 zusätzliche Timer (in einem DB) geschrieben. Die Zykluszeitmessung erfolgt durch die Sytemzeitabfrage mit SFC1, (Auswertung der Minutenzeit). Funktioniert als anhaltbare T_ON-Zeit und zeigt mir die Istzeit ms-genau an.   

Was meint Ihr dazu?


----------



## zotos (25 August 2007)

Zeig doch mal Deine Lösung. Lustiger weise habe ich gestern Abend gerade an der gleichen Geschichte gebastelt. 

Also hier meine erste Version:

```
FUNCTION FC4 : BOOL
 
VAR_INPUT
  IN : BOOL;
  PT : DINT;
END_VAR

VAR
  myDT  : DT; 
  myTOD     : TOD;
  myTime    : DINT;
  DevNull   : INT;
END_VAR

VAR_IN_OUT
  ET : DINT;
  LT : DINT;
END_VAR

BEGIN
  DevNull := READ_CLK(CDT:=myDT);  
  myTOD   := DT_TO_TOD(myDT); 
  myTime  := TOD_TO_DINT(myTOD);
  
  FC4 := FALSE;
  IF IN THEN
    IF ET >= PT THEN
      FC4 := TRUE;
    ELSE
      ET  := ET + (myTime - LT);
    END_IF;
  ELSE
    ET := 0;
  END_IF;
  LT := myTime;      
END_FUNCTION;
```
Also noch ohne Kommentare da noch ganz frisch. Eigentlich bräuchte man das ET nicht unbedingt statisch zu halten. Leider muss ich noch eine IN_OUT variable dazu setzen um eine Flanke von IN zu erzeugen. Ich habe hier im Forum gelesen das es bei dem Ergebnis von READ_CLK einen Überlauf geben kann. Das muss ich auch noch abchecken.

//Edit: An sich finde ich den Trick eher Lahm. Da es ja TON/TOF gibt. Ich wollte mir das ganze Elend nur betrachten das die S7 Programmierer ertragen müssen wenn sie auf FBs verzichten und die IN_OUT Schiene fahren.


----------



## JesperMP (25 August 2007)

Es lautet als du ein S7 programmierst.
Sprichst du vielleicht über die FC80 "TONR" die du in der TI-S7 Bibliothek finden kannst ? 
Für dieses brauchst du nicht SFC1 "READ_CLK" zu verwenden. Du kannst das #OB1_PREV_CYCLE in OB1 einfach verwenden.

edit:
Eigentlich merkwürdig, das es gibt kein retentive IEC Timer.
Ich schätze, es ist warum der FC80 Timer zu finden ist.


----------



## zotos (25 August 2007)

So ich habe gerade mal eine zweite Version erstellt. Mit zwei Modi 0=TON, 1=TOF. Den Überlauf der Systemzeit habe ich auch noch nicht gesehen und auch nicht testen können (ich werde hier noch mal im Forum suchen).
Das ganze ist nur eine Fingerübung, recht minimal im Umfang daher aber auch genügsam.


```
FUNCTION FC4 : BOOL
 
VAR_INPUT
  MODE      : INT;  (* Timermode 0=TON, 1=TOF *)
  IN        : BOOL; (* Signal *)
  PT        : DINT; (* Preset Time *)
END_VAR

VAR_IN_OUT
  ST        : DINT; (* Start Time *)
END_VAR

VAR_TEMP
  myDT      : DT; 
  myTOD     : TOD;
  myTime    : DINT;
  Fault     : INT;  (* ToDo: error logging *)
  RetVal    : BOOL; (* Function Output *)
  ET        : DINT; (* Elaps Time *)
END_VAR

BEGIN
  Fault   := READ_CLK(CDT:=myDT);  
  myTOD   := DT_TO_TOD(myDT); 
  myTime  := TOD_TO_DINT(myTOD);

  (* Set Start Time *)
  IF (MODE = 0 AND NOT IN) OR (MODE <> 0 AND IN) THEN
      ST := myTime; 
  END_IF;
  
  (* Calculate Elapse Time *)    
  ET := myTime - ST;

  (* Switch Mode *)
  IF MODE <> 0 THEN
    (* Mode: TOF *)
    IF NOT IN THEN      
      IF ET >= PT THEN
        RetVal := FALSE;
      ELSE
        ET  := ET + (myTime - ST);      
      END_IF;
    ELSE
      RetVal := TRUE;  
    END_IF;
  ELSE
  (* Mode: TON //default*)
    RetVal := FALSE;
    IF IN THEN  
      IF ET >= PT THEN
        RetVal := TRUE;
      ELSE
        ET  := ET + (myTime - ST);
      END_IF;
    END_IF;
  END_IF;
  
  FC4 := RetVal;
END_FUNCTION;
```


----------



## Hartmut Lux (26 August 2007)

Als Anhang der Code im PDF-Format.
372 byte für den FB, 1050 für den zugehörigen DB.
Freigabe und Start zusammen angesteuert ergibt normale Einschaltverzögerung. 
"Istzeit" kann bei Bedarf auch nach Time umdeklariert werden.


----------



## Larry Laffer (26 August 2007)

Hartmut Lux schrieb:


> Was meint Ihr dazu ?


 
Hallo Hartmut,
das mit deiner Indexierung (Timer 0 .. 99) wird so nicht funktionieren.
Wenn du deinen FB nochmals aufrufst (für einen neuen Timer), dann wirst du dazu aufgefordert einen neuen DB zu nehmen (anzulegen). Das heißt, den Index kannst du dir sparen. Der bildet sich automatisch durch zusätzliche DB's (ähnlich wie beim IEC-Timer SFB4, SFB5).


----------



## zotos (26 August 2007)

Ein FB?
Dann kann ich ja gleich die IEC Timer TON TOF nehmen. 
Wobei ich bei einem FC auch den von JesperMP genannten aus der lib nehmen kann.


----------



## Hartmut Lux (27 August 2007)

@ Larry Laffer: Das mit der Inidizierung der Timer funktioniert definitiv. Der Baustein ist getestet und im Einsatz. Man kann einen FB auch mehrmals mit dem gleichen DB aufrufen. Es ändert sich eben nur die Timer-Nr.

Der Vorteil ist, auch gegenüber Siemens(@ Zotos),daß man nur einen DB pro hundert Timer hat und nicht 100. 

Der generelle Vorteil dieser Timer aber ist: man kann die Zeit belibig unterbrechen und weiterlaufen lassen ohne ein zusätzliches "Umschaufeln" des Istwertes. Z.B. gut für zeitbedingtes Abschalten, wenn das System mal zwischendurch aus ist. Der Zeitwert läuft sozusagen als Rampe deren Hochlauf zwischendurch angehalten werden kann. 

Das Aufsummieren der Zykluszeit ist dabei einfacher und sicherer als eine Berechnung der Zeitdifferenz aus der Systemzeit.

Als Anhang nochmal der FB statt dem Quelltext(als Mini-Bibliothek).


----------



## Hartmut Lux (27 August 2007)

Nochmal zur Erklärung: solche FB's sollten aus Speichergründen kein Ersatz für die S5-Timer sein, sondern sind gut für verstellbare bzw. berechnete Zeiten.  Das Thema ist nur eine alternative Möglichkeit zu Zählern und Differenzberechnungen.


----------



## Larry Laffer (27 August 2007)

...
schon verstanden.
Ich hätte es nur als Multi-Instanz-FB aufgezogen (hatte ich ja schon geschrieben).
Selber habe ich auch einen ähnlichen FB für die Laufzeit-Erfassung (Betriebszeit) von Aggregaten. Er ist halt nur ahnlich angelegt wie die Siemens System-Bausteine.

Wie auch immer, es läßt sich, je nachdem wie man es aufzieht ja als Ergänzung zu den vorhandenen Funktionen machen ...


----------



## JesperMP (28 August 2007)

Ich verwende die IEC timer SFB4 und SFB5 und den retentive FC80 timer.
Mit die IEC timern verwende ich multiinstanzen und brauche denn keine 100 DBs für 100 timers.
Den FC80 braucht kein DBs.



			
				Hartmut Lux schrieb:
			
		

> solche FB's sollten aus Speichergründen kein Ersatz für die S5-Timer sein, sondern sind gut für verstellbare bzw. berechnete Zeiten


Denn tu ich offenbar etwas ganz falsch. Ich verwende fast nie die S5 timern.

Dein idee ist gut, aber nicht original. Wie du es beschreibst hast du den FC80 nachgemacht.


----------



## derwestermann (24 Januar 2008)

Bei mir sieht so was folgendermaßen aus:

FUNCTION FC 18 : VOID
TITLE =
VERSION : 0.0

VAR_INPUT
  Zeit : TIME ; //Zeitwert im Format Time für die Ausrichtung, bei t#0s arbeitet der FC nicht
  Run : BOOL ; //Laufvariable des Antriebes (Schütz), ohne Run arbeitet der Baustein nicht
END_VAR
VAR_IN_OUT
  Takt : BOOL ; //Positioniertakt
  Runtime : TIME ; //Laufzeitsammler
  TimeStamp : TIME ; //Zuletzt gelesene Zeit
END_VAR
VAR_TEMP
  TempTime : TIME ; //Zwischenspeicher für die gelesene Zeit
END_VAR
BEGIN
NETWORK
TITLE =
      U     #Takt; 
      SPB   A7d0; 
      L     T#0MS; 
      T     #Runtime; 
A7d0: CLR   ; 
      CALL SFC   64 (
           RET_VAL                  := #TempTime);
      CLR   ; 
      UN    #Run; 
      SPB   A7d2; 
      L     #TempTime; 
      L     #TimeStamp; 
      -D    ; 
      L     #Runtime; 
      +D    ; 
      T     #Runtime; 
A7d2: CLR   ; 
      L     #TempTime; 
      T     #TimeStamp; 
      L     #Runtime; 
      L     #Zeit; 
      >=D   ; 
      R     #Takt; 
      BE    ; 

END_FUNCTION

Und hier der Aufruf bei der Ausrichtung von Paletten nach Typ und damit größe:

// --- Type E ----------------------------
      L     T#6S700MS
      T     #AusrichtZeit
      L     "FA_DB142".PC5171.dd.TYP.A2[1]
      L     'E'
      ==I   
      SPB   ladn
// --- Type I ----------------------------
      L     T#6S500MS
      T     #AusrichtZeit
      L     "FA_DB142".PC5171.dd.TYP.A2[1]
      L     'I'
      ==I   
      SPB   ladn
// --- Type C ----------------------------
      L     T#6S500MS
      T     #AusrichtZeit
      L     "FA_DB142".PC5171.dd.TYP.A2[1]
      L     'C'
      ==I   
      SPB   ladn
      SET   
      =     #NoTime
      L     T#0MS
      T     #AusrichtZeit
ladn: NOP   0
      CALL  FC    18
       Zeit     :=#AusrichtZeit
       Run      :="KC5171R"
       Takt     :="C5171T1VX"
       Runtime  :="DB_Ausricht".C5171_Runtime
       TimeStamp:="DB_Ausricht".C5171_TimeStamp


----------



## Lars Bizare (28 Januar 2008)

eine Frage zum FC80...

Ich hab das mal auf dem PG simuliert und bekomme bei Delta_T = 1 und PV = 6 000 immer eine Abweichung von etwar 4-5 sec.

Hab das mit der Stopuhr getestet und der FC80 hatte immer 64-65s gebraucht.
Kann das am PG liegen oder muss ich da noch was beachten?


----------



## derwestermann (28 Januar 2008)

Auf dem PG heißt so viel wie mit dem Simulator?  
Versuch's mal mit einer reellen SPS, das sollte gehen.  
Handelt es sich um eine reelle SPS, versteh' ich's auch nicht.


----------



## Hartmut Lux (29 Januar 2008)

Hoppla JesperMP, Probleme mit dem FC80? Ist manchmal doch besser das zu bemühen was zwischen den eigenen Ohren sitzt.
Meine Bausteine nutzen intern die SFC1, funzt auch im Simulator...

Es geht hier um eigentlich um Programmierstrategien. Wenn dieses Prinzip bekannt ist um so besser. Ich nutze dieses Prinzip, ja nicht nur in Timerbausteinen sondern auch bei Rampen und Ablaufsteuerungen, welche bei Zeitgesteuertem Verhalten z.B genau da weitermachen können wo sie angehalten wurden.

@derwesterman: sollte Deine CPU mal längerfristig eingeschaltet bleiben (>23d) ist bei der Zeitdifferenzbildung eine Überlaufbehandlung notwendig. Die SFC1 bringt bei 300-er Steuerungen übrigens eine bessere Zeitauflösung als die SFC64.


----------

