Zeitmessung TwinCAT 2

BauerJnr

Level-1
Beiträge
8
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

wahrscheinlich eine sehr einfache Frage, aber ich bin damit leider schon überfordert.
Ich habe 2 verschiedene Programme die zu unterschiedlichen Tasks gehören. In dem einen werden Daten gesendet und in dem anderen Daten empfangen.
Jetzt wollte ich gerne die Zeit messen, wie lange es dauert, bis auf die gesendeten Daten eine Antwort kommt. Also muss ich in dem einen Programm einen Timer starten und in dem anderen Programm diesen wieder anhalten.
Wie kann ich das realisieren?

Vielen Dank schon mal!
 
Da die Task's gemeinsam auf die globalen Variablen zugreifen können ist die Lösung nicht schwierig:

Task eins speichert zum gewünschten Zeitpunkt den über getsystemtime erfassten Betriebssystemzeitstempel in einer beliebigen Variable. Task 2 errechnet dann jeweils die Differenz.
Für kurze Zeitabstände nehme ich bequemerweise meist nur das LowDW. In dem Falle muss aber der Überlauf auf das HighDW u.U. berücksichtigt werden (plausibilität).

Du startest also keinen Timer, sondern liest einen freilaufenden Timer aus. Die STandardtimer arbeiten übrigens nach dem gleichen Prinzip.
Bei Zykluszeiten im Millisekundenbereich kannst Du auch den FB_LocalSystemTime nehmen, da hast Du direkt ohne Umrechnung millisekundengenaue Zeitstempel.
 
Zuletzt bearbeitet:
Vielen Dank für den Tipp, ich habe es jetzt über den FB_LocalSystemTime realisiert.
Die Systemzeit wollte ich jetzt in einem Array speichern und in dem anderen Task wieder darauf zugreifen. Nun tritt bei mir ständig das Problem auf, dass mein Zählindex von dem Array nicht bei 0 beginnt, sondern willkürlich bei irgendwelchen Zahlen. Habe es schon mit "urlöschen" probiert, aber das Phänomen tritt immer wieder auf. Woran kann das liegen?

Edit: Bzw. meine Zählvariable beginnt bei 0 und springt beim ersten Mal inkrementieren auf einen beliebigen Wert.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie incrementierst Du? Eventuell über einen Trigger, der mehr als einen Zyklus True ist? Dann würde dieses Verhalten eine einfache Erklärung haben.
Stell einfach betreffenden Quelltext hier rein...
 
Späte Antwort, bin heute erst aus dem Urlaub zurück.
Anhang anzeigen 38440

In Zeile 46 wird meine Variable inkrementiert. Die Anweisung steckt in einer for-Schleife und einer If-Bedingung, die maximal einmal pro Zyklus erfüllt sein kann.
Sie wird auch wie erwartet nur dementsprechend inkrementiert, nur der Startwert ist halt nie bei 0, sondern direkt nach dem ersten Inkrementieren bei einer willkürlichen Zahl. Von der aus wird dann normal weiter inkrementiert.
 
Hallo BauerJnr,
Dein Bild lässt sich leider nicht öffnen. Die Variable wird schon vor dem ersten inkrementieren einen willkürlichen Wert haben. Hast Du der Variable beim Deklarieren denn mit := einen Wert vorgegeben? Dann sollte das Problem eigentlich nicht bestehen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
VAR
 [...]
 TimeCounter: UINT := 0;
[...]
END_VAR
 IF Bool_MessageReceived THEN        
 FOR i := 0 TO (Input.NoOfRxMessages - 1) DO     
  IF MessageReceived[i].cobID = 386  THEN     
Zaehler_CRDX[CounterCRDX] := (MessageReceived[i].rxData[1] * 256) + MessageReceived[i].rxData[0]; 
   IF CounterCRDX < 2000 THEN
CounterCRDX := CounterCRDX + 1;
   END_IF

fbTime();
timeStack := fbTime.systemTime.wMilliseconds;
   Zeitmessung[TimeCounter] := global_systemTime[TimeCounter].wMilliseconds -timeStack;
   IF Zeitmessung[TimeCounter] < 0 THEN (* Falls Überlauf *)
    Zeitmessung[TimeCounter] := Zeitmessung[TimeCounter] + 1000;
   END_IF
TimeCounter := TimeCounter + 1;
 [...]
TimeCounter ist meine Zählvariable. Ja das habe ich gemacht. Habe zusätzlich noch einen Schritt "Init" eingebaut, wo am Anfang des Programms alle Werte auf 0 gesetzt werden. Das funktioniert auch, aber das Problem tritt ja erst beim ersten mal Inkrementieren auf. Bin zwar nicht besonders talentiert in sowas, aber das macht für mich keinen Sinn.
 
Zuletzt bearbeitet:
Ich nehme mal an, dass If-Konstrukt soll negative Zeitwerte verhindern, falls der Timer während der Messung überläuft. Das geht viel eleganter in dem Du die Subtraktion in ein ABS() einschließt.
In Deinem Codeausschnitt ist kein END-FOR zu sehen, was bedeutet, dass die Erhöhung von TimeCounter innerhalb der For-Schleife stattfindet und eventuell mehrmals erfolgt.
 
Zuletzt bearbeitet:
Wenn ich mich nicht verzählt habe, ist das IF-Konstrukt nicht vollständig. Irgendwie fehlt da was, und solange bleibt die Anfangsvermutung, das TimeCounter länger als einen Zyklus gezählt wird.
Am Ende des Snippets fehlt mir jedenfalls 2x end_if und 1x end_for.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja ich hab nur das relevante mit rein geschrieben. Danach erfolgen nur noch ein paar Zuweisungen etc.. Das hab ich mir auch im Sampling Trace angeschaut, dass die Variable in jedem Zyklus nur um 1 inkrementiert wird. Das Problem ist halt der Sprung von 0 auf 17899 oder Ähnliches. Danach wird die Variable ganz normal weitergezählt

Edit: Inzwischen passiert das auch mit meiner Variable: CounterCRDX. Die ist eben auf den Wert 16384 gesprungen, obwohl die IF-Abfrage ja verhindert, dass diese Variable größer als 2000 werden kann. Bin absolut ratlos...
 
Zuletzt bearbeitet:
Mehrfachzuweisungen, Adressüberschneidungen?
Kommst Du aus der Hochsprachenprogrammierung? Die zyklische, nicht blockierende Abbarbeitung in einem typ. SPS-Programm ist Dir bekannt? "Multitasking" ist eine rel. neuere Fähigkeit von Industriesteuerungen. Grundsätzlich kann man die typ. Industriesteuerung als Single-Task-System verstehen.

Ohne etwas mehr Code haben wir keine Chance, Dein Problem zu verstehen.
 
Zuletzt bearbeitet:
... Edit: Inzwischen passiert das auch mit meiner Variable: CounterCRDX. Die ist eben auf den Wert 16384 gesprungen, obwohl die IF-Abfrage ja verhindert, dass diese Variable größer als 2000 werden kann. Bin absolut ratlos...
16384 ist doch 4000h und das ist 2000h gar nicht so unähnlich ;o)
Stimmt da die Betrachtungsweise nicht (dezimal/hexadezimal)? Oder inkrementierst Du das HighByte?
 
Zurück
Oben