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

Hartmut Lux

Level-1
Beiträge
68
Reaktionspunkte
77
Zuviel Werbung?
-> Hier kostenlos registrieren
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:cool:.

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

Also hier meine erste Version:
Code:
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.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
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.
 
Zuletzt bearbeitet:
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.

Code:
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;
 
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.
 

Anhänge

  • FB84.pdf
    21,6 KB · Aufrufe: 225
Zuviel Werbung?
-> Hier kostenlos registrieren
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).
 
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.
 
@ Larry Laffer: Das mit der Inidizierung der Timer funktioniert definitiv:cool:. 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).
 

Anhänge

  • T_on_s.zip
    17,3 KB · Aufrufe: 214
Zuviel Werbung?
-> Hier kostenlos registrieren
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.
 
...
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 ...
 
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.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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
 
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?
 
Zuletzt bearbeitet:
Auf dem PG heißt so viel wie mit dem Simulator? :rolleyes:
Versuch's mal mit einer reellen SPS, das sollte gehen. :cool:
Handelt es sich um eine reelle SPS, versteh' ich's auch nicht. :confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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.
 
Zurück
Oben