Zeitmessung in Structur Text

Leto

Level-1
Beiträge
53
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin moin,

ich muss bei TwinCat eine Zeitmessung realisieren. Das ganze soll folgender Maßen realisiert werden:

Mittels negativer Flanke eines digitalen Eingangs wird die Zeitmessung gestartet. Bei der zweiten negativen Flanke des selben digitalen Eingangs soll die Zeitmessung gestoppt werden, die gemessene Zeit in ms in eine Variable kopiert werden und gleichzeitig die Zeitmessung neu gestartet werden.

Die Messung dient zur Ermittlung der Zykluszeit einer Anlage.

Hat jemand einen Vorschlag, wie ich dieses Problem in ST lösen kann?

Vielen Dank im Vorraus.

Gruß
 
Eine Zählvariable in jedem Programmzyklus um 1 erhöhen. Bei der digitalen Signalflanke die Zählvariable in eine andere kopieren und dann wieder auf 0 setzen. Anlagenzyklus = Zähler * Taskzykluszeit.
 
Mit dem Gedanken hatte ich auch schon gespielt, nur bin ich leider ein Anfänger in Sachen ST und wüsste nicht wie ich das codieren soll.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
VAR
  timer : TON;
END_VAR

timer(PT:=t#1000s,IN:=FALSE);
timer(in:=TRUE);


time := timer.ET;

Du musst den Timer aber nicht zweimal aufrufen, was soll denn das überhaupt bringen? Einmal IN:=False und gleich danach IN:=TRUE? Da kann der Timer doch gar nicht starten.

Mach es so:
Code:
timer(IN:={Startbedingung,bool},PT:={länger als die längste mögliche Taktzeit,time});
time := timer.ET; (*So wie im vorigen Beispiel angegeben*)
 
Ich bin mir zwar nicht sicher ob das TwinCat anbietet, aber normalerweise kannst du ja bei fallender Flanke die Systemzeit auslesen auf ein Variable speichern. Bei der zweiten fallenden Flanke wieder Systemzeit auslesen und die zuvor gespeicherte Zeit subtrahieren = Vergangene Zeit und zugleich wieder auf Zeitstempel für die nächste Messeung.

Gruß
M_o_t
 
Hi

Ich hatte schon einmal fast die selbe Aufgabenstellung, hab das so gelöst:

Erste Flanke -> Timer 1 startet.

Zweite Flanke -> Timer 1 Stopt und Timer 2 startet, zusätzlich wird die gemessene Zeit von Timer 1 gespeichert (Merkerword, DB, ...)

Dritte Flanke -> Timer 2 Stopt und Timer 1 Startet wieder, Zeit von Timer 2 überschreibt gespeicherte Zeit.

Hab den Timerwechsel einfach mit einer FlipFlop schaltung gemacht. (Stromstoßschalter)


Hoffe ich konnte dir weiterhelfen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bietet noch jemand mehr Timer?

Code:
VAR
   ZyklusZaehler:UDINT;
   GemesseneZeit:TIME;
END_VAR;


IF Triggerflanke
THEN
   GemesseneZeit:=UDINT_TO_TIME(Zykluszaehler*Taskzykluszeit);
   Zykluszaehler:=0;
END_IF;
ZyklusZaehler:=ZyklusZaehler+1;
 
Ok, danke.

Jetzt habe ich aber noch eine abschließende Frage:

Wie kann ich in ST einen digitalen Eingang auf die positive oder negative Flanke abfragen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok. Hab es dann doch über die Suche gefunden in ST.

Code:
VAR   
    timer :TON;
    GemesseneZeit:TIME;
    ZyklusZaehler:UDINT;
    fStartflanke: R_TRIG;
END_VAR

Code:
fStartflanke(CLK:= DI_Conv1TriggerPosNotReached);
IF (fStartflanke.Q) THEN
   GemesseneZeit:=UDINT_TO_TIME(Zykluszaehler*10); (*10 = 10ms Taskzyklus *)
   Zykluszaehler:=0;
END_IF;
ZyklusZaehler:=ZyklusZaehler+1;

Sollte so funktionieren denke ich.

Vielen Dank an alle
 
Zuletzt bearbeitet:
Ja, die sind mir bekannt, nur deren Aufruf mittels Structur Text leider nicht.

Als erstes deklarierst du eine Variable vom Typ R_Trig bzw. F_Trig und den Eingang:

Code:
fbRTrig: R_TRIG;
bInput1 AT %I*: BOOL;

Dann musst du den entsprechenden digitalen Eingang einbauen:

Code:
fbRTrig(CLK:= bInput1);

Zum Schluss musst du den Baustein noch auswerten:

Code:
fbRTrig();
IF NOT fbRTrig.Q THEN[INDENT]/* Dein Code */[/INDENT]
END_IF
 
A
Zum Schluss musst du den Baustein noch auswerten:

Code:
fbRTrig();
IF NOT fbRTrig.Q THEN[INDENT]/* Dein Code */[/INDENT]
END_IF

Es reicht aber, die Funktion einmal aufzurufen. Den 2.Aufruf fbRTrig(); kannst Du Dir sparen.

Code:
IF NOT fbRTrig.Q THEN[INDENT]/* Dein Code */
[/INDENT]
END_IF
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es reicht aber, die Funktion einmal aufzurufen. Den 2.Aufruf fbRTrig(); kannst Du Dir sparen.

Code:
IF NOT fbRTrig.Q THEN[INDENT]/* Dein Code */
[/INDENT]
END_IF

Aber nur wenn der erste Aufruf zyklisch aufgerufen wird. Passiert der erste Aufruf in einem Case-Step und die Abfrage in einem anderen Case-Step, dann muss vor der Abfrage erst der Baustein aktualisiert werden, wie in meinem Beispiel.
 
Ich will jetzt auf keinen Fall eine Grundsatzdiskussion starten oder jemanden angreifen. Die Case Funktion war nicht ersichtlich.
Aber ich würde in so einem Fall den ersten Aufruf durch

Code:
fbRTrig.CLK:= bInput1;

ersetzen.

Das wäre aus meiner Sicht sauberer. So bleibt es bei einem zyklischen Aufruf.

Aber verwendet der TE überhaupt ein Case? Wahrscheinlich nicht....

Darum würde ich Ihm empfehlen:

Code:
fbRTrig(CLK:= bInput1);
If fbRTrig.Q Then
..
 
Zurück
Oben