TIA TIA V16 gewollte Dateninkonsistenz im Zeitgesteuerten OB (30) ???

NBerger

Level-3
Beiträge
1.414
Reaktionspunkte
395
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Habe da mal wieder ein Problem:

Ich lese im OB1 (Zyklisch) die Lokalzeit aus und weise diese als Uhrzeit einer TIME Variablen zu.

Code:
#RETURNVALUE := RD_LOC_T("Akt".Localzeit);

"Akt".Uhrzeit := DTL_TO_TOD("Akt".Localzeit);
"Akt".Uhrzeit wird nur hier geschrieben !!!

Die "Akt".Uhrzeit nutze ich unter anderem im OB30 (alle 100ms).

In genau diesem OB kommt es nun sporadisch zu Fehler. In diesen Fällen ist die "Akt".Uhrzeit = t#0s (also Mitternacht) (im zyklischen Programm geschieht dies nicht)

Als temporäre Lösung vergleiche ich die Variable im OB30 auf 0 und beschreibe bei ungleich eine weitere Uhrzeitvariable mit der "Akt".Uhrzeit.

Das funktioniert jetzt erstmal, ABER ich habe Angst!!!

"Akt".Uhrzeit ist vom Typ TIME, also ein Doppelwort!

Das Verhalten scheint nun so zu sein: Im OB1 wird mit
Code:
"Akt".Uhrzeit := DTL_TO_TOD("Akt".Localzeit);
die Akt".Uhrzeit zunächst gelöscht (T#0s) dann der neue Wert ermittelt und zugewiesen wird. Kommt genau jetzt ein Zeitalarm (OB30 Aufruf) hat die Variable "Akt".Uhrzeit einen FALSCHEN Wert !!!

Kann das mit jeder Variablen geschehen ??? Ist hier global die Datenkonsistenz in Gefahr ???

Muss ich jetzt jede Variable die ich in einem Zeit-OB lese dreifach anlegen und um zyklischen Programm nacheinander zuweisen damit ich im Zeit-OB auswerten kann ob zumindest die ersten oder letzten zwei Werte gleich sind (also konsistent)???

Edit: TIA V16.0.0.3 CPU 1511F 6ES7 511-1FK01-0AB0 V2.8.3
 
Zuletzt bearbeitet:
Schau dir mal die Befehle DIS_IRT / EN_IRT und DIS_AIRT / EN_AIRT an.
Vielleicht hilft es.
Ich hätte zwar erwartet, dass RD_LOC_T nicht unterbrochen wird, aber bei TIA gibt es immer mal wieder "Überraschungen"
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Schau dir mal die Befehle DIS_IRT / EN_IRT und DIS_AIRT / EN_AIRT an.
Vielleicht hilft es.
Im Grunde ja,aber: Ein Start wird nicht verschoben sondern einfach eleminiert. Ein Regler wird dann einfach nicht aufgrufen. (macht es nicht besser... und Taktynchrone aufrufe gehen auch verloren MC-Motion lässt grüßen...

Habe mal nen Service-Request gestellt, mal schauen...

P.S.: Bin ja mal auf die Ausrede gespannt warum eine Variable erst abgelöscht wird vor der eigendlichen Zuweisung!
 
Hallo,


Das Verhalten scheint nun so zu sein: Im OB1 wird mit
Code:
"Akt".Uhrzeit := DTL_TO_TOD("Akt".Localzeit);
die Akt".Uhrzeit zunächst gelöscht (T#0s) dann der neue Wert ermittelt und zugewiesen wird. Kommt genau jetzt ein Zeitalarm (OB30 Aufruf) hat die Variable "Akt".Uhrzeit einen FALSCHEN Wert !!!

Kann das mit jeder Variablen geschehen ??? Ist hier global die Datenkonsistenz in Gefahr ???

Wenn das so wäre müsste das aber 2 Bug's sein, warum sollte die ":=" Anweisung zuerst 0 und danach den richtigen Wert schreiben? Und eigenltich sollte die Unterbrechung durch den OB ja nicht innerhalb einer Anweisung möglich sein. Ich würde erwarten dass der OB30 entweder nach dem "DTL_TO_TOD" und vor dem ":=" ausgeführt wird, dann müsste noch die alte Zeit in "Akt".Uhrzeit stehen. Ansonsten dürfte er ja erst wieder nach dem ":=" ausgeführt werden.
 
Kommt denn am RetVal immer 0 an ( 0 = fehlerfrei )?
Hast du dies einmal geprüft bzw kannst du mal ein paar Zeilen einfügen dass der RetVal bei <>0 weggesichert wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn das so wäre müsste das aber 2 Bug's sein, warum sollte die ":=" Anweisung zuerst 0 und danach den richtigen Wert schreiben? Und eigenltich sollte die Unterbrechung durch den OB ja nicht innerhalb einer Anweisung möglich sein. Ich würde erwarten dass der OB30 entweder nach dem "DTL_TO_TOD" und vor dem ":=" ausgeführt wird, dann müsste noch die alte Zeit in "Akt".Uhrzeit stehen. Ansonsten dürfte er ja erst wieder nach dem ":=" ausgeführt werden.

Ist aber leider so. Im OB30 kommt halt sporadisch T#0s an...
 
Im Grunde ja,aber: Ein Start wird nicht verschoben sondern einfach eleminiert. Ein Regler wird dann einfach nicht aufgrufen. (macht es nicht besser... und Taktynchrone aufrufe gehen auch verloren MC-Motion lässt grüßen...

Hmmm ... War nicht der Unterschied zwischen DIS_IRT und DIS_AIRT, dass DIS_IRT den Prozessalarm verwirft und DIS_AIRT den Prozessalarm verzögert?
 
In "Akt".Localzeit steht definitiv immer eine gültige Zeit und im OB1 wird "Akt".Uhrzeit definitiv nicht T#0s.

Habe das mit "Fangschaltungen" überprüft die mir jeweils ein Bit setzen wenn es so auftreten würde, werden aber nicht gestzt (Im OB30 schon).

Edit: Was mir da einfällt: Habe die letzten Tage die CPU getauscht. Vorher war da eine 1511 drin mit Firmware 1.8x.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Im OB1:
Code:
"Akt".Uhrzeit := DTL_TO_TOD("Akt".Localzeit);

IF "Akt".Uhrzeit = t#0s THEN
    "Tag_2" += 1;
END_IF;

Im OB30:
Code:
IF "Akt".Uhrzeit = t#0s THEN
    "Tag_3" += 1;
END_IF;

Variablentabelle nach ca 1 Minute:

Inkonsistenz.JPG

Edit:
Hmmm ... War nicht der Unterschied zwischen DIS_IRT und DIS_AIRT, dass DIS_IRT den Prozessalarm verwirft und DIS_AIRT den Prozessalarm verzögert?
Hast ja Recht...
 
Zuletzt bearbeitet:
Hallo Nberger,

nur mal aus Interesse. Hast du die Variable im Ob1 mal noch auf einen Temp und dann auf den Db kopiert?
ist dein Ob1 und Ob30 optimiert? Ist der Db Optimiert?

Gruß Tia
 
Ich hatte schon früher die Vermutung, dass da mit den Weckalarmen etwas nicht stimmt! Undzwar wenn der OB35 durch den OB122 unterbrochen wird, im Zusammenspiel mit Unterbrechungen des OB1 durch den OB122...

Aber so sachen sind schon schwer nachzustellen. Komisch, dass bei Dir das so oft auftritt. Sollte ja statistisch nicht so oft vorkommen, dass Dein OB1 gerade an dieser Stelle unterbrochen wird. Oder hast Du zum testen nur diesen kurzen Code im OB1?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Habe da mal wieder ein Problem:

Ich lese im OB1 (Zyklisch) die Lokalzeit aus und weise diese als Uhrzeit einer TIME Variablen zu.

Code:
#RETURNVALUE := RD_LOC_T("Akt".Localzeit);

"Akt".Uhrzeit := DTL_TO_TOD("Akt".Localzeit);

Evtl. macht da der Compiler was ganz anderes draus, was dann nicht richtig unterbrochen werden kann. Gab ja schon öffter Probleme mit dem "Codeoptimieren" vom Compiler...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich lese im OB1 (Zyklisch) die Lokalzeit aus und weise diese als Uhrzeit einer TIME Variablen zu.
Warum ist "Akt".Uhrzeit vom Datentyp TIME (und nicht TOD)?
Implizite Konvertierung TOD zu TIME geht nur ohne IEC-Prüfung. Daher besser explizit:
"Akt".Uhrzeit := TOD_TO_TIME(DTL_TO_TOD("Akt".Localzeit));

"Akt".Localzeit ist DTL?
Wird der DB "Akt" irgendwo indirekt adressiert beschrieben? Oder teilweise blockweise beschrieben?

Multitasking-geeigneter würde ich das so machen:
Code:
VAR_TEMP
  OB1_Localzeit : DTL;
  RETURNVALUE : INT;
END_VAR

#RETURNVALUE := RD_LOC_T(#OB1_Localzeit);
"Akt".Localzeit := #OB1_Localzeit;
"Akt".Uhrzeit := TOD_TO_TIME(DTL_TO_TOD(#OB1_Localzeit));

Harald
 
Multitasking-geeigneter würde ich das so machen:

Und warum ist das "Multitasking geigneter? Das Problem bleibt das gleiche!

Zykluszeit: ~2ms

nur mal aus Interesse. Hast du die Variable im Ob1 mal noch auf einen Temp und dann auf den Db kopiert?

Ja das geht, aber ist ja auch nicht verwunderlich: Die Tempvariable wird ja nicht im OB30 verwendet!

Einfache Zuweisungen scheinen ja auch konsistent zu sein. Problematisch ist eher der DTL_TO_TOD.

ist dein Ob1 und Ob30 optimiert? Ist der Db Optimiert?
Ja, Ja und Ja
 
Zuletzt bearbeitet:
Multitasking-geeigneter würde ich das so machen:
Und warum ist das "Multitasking geigneter?
Der RD_LOC_T kann unterbrochen werden, während er in Deiner Programmierung "Akt".Localzeit beschreibt, und während der Unterbrechung könnte "Akt".Localzeit überschrieben werden --> Inkonsistent! In meiner Variante mit der TEMP-Variable kann die TEMP-Variable während der Unterbrechung nicht verändert werden.

(Eigentlich wollte ich in meinem Beitrag #15 noch fragen, ob "Akt".Localzeit noch irgendwo beschrieben wird. Irgendwie ist die Frage beim Beitrag formulieren verloren gegangen...)

Nachtrag:
Die Unterbrechung kann bei meiner Variante auch während " "Akt".Localzeit := #OB1_Localzeit; " stattfinden und "Akt".Localzeit überschreiben (das wäre dann ein Problem Deines restlichen Programms). Bei mir ist aber sichergestellt, daß in "Akt".Uhrzeit die Zeit ankommt, die von RD_LOC_T geliefert wird.

Harald
 
Zuletzt bearbeitet:
Problematisch ist eher der DTL_TO_TOD.

dann probier doch mal:

Code:
#RETURNVALUE := RD_LOC_T("Akt".Localzeit);

"Akt".Uhrzeit_temp := TOD_TO_TIME(DTL_TO_TOD("Akt".Localzeit));


"Akt".Uhrzeit := "Akt".Uhrzeit_temp;

evtl. weiter unten im Code alle Variablen nochmal lesen, damit der Compiler die nicht wegoptimiert. Kann man eigentlich diese Compileroptimierung noch irgendwo abschalten?
 
Zuletzt bearbeitet:
Zurück
Oben