Frage zu TON Timern in Codesys

Ja
Das hängt mit der Abarbeitung der POE zusammen. Einen Einfluss auf die Zeit hat auch die Zykluszeit des Task.
Ganz oben habe ich gedacht, dass das Fazit ist, dass ich es nicht schaffe mit den TON Timern wirklich genau zu sein, wenn die Timerzeit sehr klein gewählt wird.

Hier hast du was programmiert. Ich habe das auch nachvollzogen (Mal abgesehen von der 1,5). Denke ich jedenfalls.

Aber nur um das klarzustellen, auch in dieser Variante wird nicht jede tDurX ein Wert auf value addiert. Auch hier gibt es den Zeitfehler oder?
Der Zeitfehler wird für die If-Bedingung herausgerechnet, aber in Wirklichkeit kann es auch hier sein, dass die Berechnung des neuen Values mal bei genau 100 ms, mal bei 102 ms, ... erfolgt oder?.

Die einfachste Lösung wäre tatsächlich die zyklische Task.

Wenn es unbedingt in der freialufende Task passieren soll, sollte hier nur ein Timer verwendet werden.

Deklaration:
Code:
    meinTimer: TON;
    diZeitwert: DINT;
    diSchritt: DINT;
    diSchrittAlt: DINT;
    CNT: DINT;
    value: REAL;
    tDurY: TIME;
    diAnzahl: DINT;
    tDurX: TIME;

und Code:

Code:
diAnzahl := 50;
tDurX:= T#100ms;
tDurY:= tDurX*REAL_TO_DINT((DINT_TO_REAL(diAnzahl)+1.5));

meinTimer(PT:= tDurY, IN:= TRUE);
diZeitwert := TIME_TO_DINT(meinTimer.ET);
diSchritt := (diZeitwert - (diZeitwert MOD TIME_TO_DINT(tDurX))) / TIME_TO_DINT(tDurX);
IF diSchritt <> diSchrittAlt AND diSchritt<>0 AND diSchritt <=diAnzahl THEN
    CNT := CNT + 1;
    value := value + 100 * (TIME_TO_REAL(tDurX)/(TIME_TO_REAL(tDurY)));
END_IF;
diSchrittAlt := diSchritt;
 
Ich möchte genau alle 100 ms eine Aktion durchführen. z.B. einen Wert erhöhen, eine Funktion inkrementieren ...
==>
Die Zykluszeit ist das Zeitraster in welchen die Task aufgerufen wird.
Bei Codesys kann man wählen zwischen:
Freilaufend -> hier wird der Task aufgerufen wenn der Controller Zeit hat
Ereignisgesteuert -> Aufruf bei bestimmten Ereignis
Zeitraster -> z.B.50ms -> Hier wird die Task alle 50ms aufgerufen
 
Ich möchte genau alle 100 ms eine Aktion durchführen. z.B. einen Wert erhöhen, eine Funktion inkrementieren ...
Dann musst Du ein Ereignis oder Zyklus nehmen, was genau alle 100ms kommt. Z.B. die Task-Aufrufzeit. Wenn Du eine Task alle 10ms aufrufst, dann in der Task bis 10 zählen und dann die Aktion aufrufen. Falls Du auch noch freilaufende Task oder unsynchrone Feldbus-EA-Zyklen hast, dann wird da aber auch wieder ein Jitter bei der Verarbeitung der Aktion entstehen.
Warum muß die Aktion "genau alle 100ms" passieren? Ist alle 95..105ms nicht genau genug?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte genau alle 100 ms eine Aktion durchführen. z.B. einen Wert erhöhen, eine Funktion inkrementieren ...
Wenn es wirklich eine Punktlandung werden muss, sind Zeitbausteine wie TON, TOFF & TP nicht geeignet. Hier wäre der Weg von PN/DP der richtige.
Zur Erläuterung
Zeitbausteine funktionieren in Codesys etwas anders als bei Siemens. Die Abgelaufene Zeit wird beim Eintritt in die POE genommen und gespeichert. Das hat den Vorteil / Nachteil das wärend der gesamten Abarbeitung der POE sich der Wert von ET auch bei wiederholtem lesen nicht verändert.
Leider gibt es auch hier Außnahmen bei verschiedenen Herstellern der Controller

Die Abarbeitung mal an einem Beispiel
Angenommen ein Ton mit 100ms Laufzeit, der Taskaufruf alle 30ms.
Taskaufruf -> Aufruf der POE - Beim Eintritt in die POE wird die Zeit gelesen

1. deine POE läuft
2. in der POE startest du den Timer, verbleibende Zeit bis zum nächsten Aufruf der POE 20ms
3. nächster POE Aufruf -> Timerzeit wird gelesen ->20ms - kleiner als Sollzeit, Q = False
4. nächster POE Aufruf (30ms später) -> Timerzeit wird gelesen -> 50ms - kleiner als Sollzeit, Q = False
5. nächster POE Aufruf (30ms später) -> Timerzeit wird gelesen -> 80ms - kleiner als Sollzeit, Q = False
6. nächster POE Aufruf (30ms später) -> Timerzeit wird gelesen -> 110ms - größer als Sollzeit, Q = True

Je kleiner die Aufrufzeit der Task je kleiner ist der Fehler - er verschwindet aber nicht.
Ich hoffe das verdeutlicht etwas dein Problem mit der genauen Zeiterfassung
 
Ich glaube den Sachverhalt habe ich verstanden. Aber danke nochmal für die ausführliche Erläuterung.

Wenn es sehr genau sein muss, funktioniert das mit den Timern nicht.

Ich habe jetzt einen Task laufen, der alle 100 ms eine globale Variable verändert. Das scheint etwas genauer zu sein, aber 100 % genau klappt es damit gefühlt auch nicht.

Dann musst Du ein Ereignis oder Zyklus nehmen, was genau alle 100ms kommt. Z.B. die Task-Aufrufzeit. Wenn Du eine Task alle 10ms aufrufst, dann in der Task bis 10 zählen und dann die Aktion aufrufen. Falls Du auch noch freilaufende Task oder unsynchrone Feldbus-EA-Zyklen hast, dann wird da aber auch wieder ein Jitter bei der Verarbeitung der Aktion entstehen.
Warum muß die Aktion "genau alle 100ms" passieren? Ist alle 95..105ms nicht genau genug?
Ich hab das jetzt nur zu Lernzwecken gemacht, um die Funktionsweise der Timer richtig zu verstehen und anwenden zu können.

Nochmals danke an alle
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bedeutet? Kannst du mal Fakten nennen? Statt 100ms sind es nur 99,999ms oder 94ms..... oder 100,01ms....???
Wie stellst du fest dass es nicht 100%ig passt? Oder ist das ein Bauchgefühl?
Ich habe kein Oszilloskop dran, aber ich kann die Dauer tDurY erhöhen, dann steigt der Fehler auch. Und bei der Timer Version (In 20s bis 196 gezählt) ist der Fehler größer als bei der Task Version (Bei 20s bis 199 gezählt).
 
In dem FB, indem sich der 20 s Timer befindet wird eine Variable geändert, sobald Timer.Q = True. Diese Variable ist global und befindet sich in dem anderen Task. Dort wird sie abgefragt. Nur wenn die Variable True ist, wird auch die Zahl inkrementiert.
Ich behaupte mal, die Steuerung und der Task laufen sehr genau, es liegt eher ein Gedankenfehler vor ( durch die zwei Tasks ).
 
Weil die SPS zyklisch arbeitet, schwanken alle erzeugten Zeiten durchschnittlich +/- ca. einen halben Zyklus. Man muß für die Aufgabe ein Toleranzfenster festlegen, wie genau man die Zeiten tatsächlich braucht, und nicht exakt genaue Zeiten erwarten.
Das ist ähnlich, wie wenn man einen analogen Messwert auf exakt mw = 123.456 abfragen will. Da muß man auch ein gewisses Toleranzfenster oder Totband festlegen.

Harald
 
Alles klar. Danke
Weil die SPS zyklisch arbeitet, schwanken alle erzeugten Zeiten durchschnittlich +/- ca. einen halben Zyklus. Man muß für die Aufgabe ein Toleranzfenster festlegen, wie genau man die Zeiten tatsächlich braucht, und nicht exakt genaue Zeiten erwarten.
Das ist ähnlich, wie wenn man einen analogen Messwert auf exakt mw = 123.456 abfragen will. Da muß man auch ein gewisses Toleranzfenster oder Totband festlegen.

Harald
Alles klar. Danke
 
Zurück
Oben