Für dieses Forum muß Javascript im Browser aktiviert werden!
Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C2 Quellcode formatieren: <code>Quellcode</code> ASM Quellcode formatieren: <asm>Quellcode</asm> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! > > > Hallo Zusammen, > > > > > > ich habe Probleme mit einem Thread, der den Systemtimer verwendet. > > > Nach ca. 14 Tagen funktioniert er nicht mehr richtig, nach vier Wochen > > > werden die Fehlfunktionen so groß, daß ich einen Reset machen muß. > > > > > > Grundsätzlich stehe ich mit der long Variable auf Kriegsfuß; obwohl ich mich > > > meiner Meinung nach an die Spec halte, gibt es bei großen Zahlenwerten immer Probleme. > > > > > > Deshalb glaube ich auch, daß der große Zahlenwert des system.timer() Ursache für die > > > Probleme dieses Threads sind. Vielleicht erkennt ja einer von Euch sofort, was ich hier falsch mache. > > > > > > Anbei der Code. > > > Grundsätzliche Funktion des Threads: > > > Mehrere Funktionen nacheinander ausführen. > > > Beispiel: Jalousien runterfahren und nach 20 Sekunden abschalten > > > oder > > > Licht aufziehen, nach einiger Zeit runterdimmen, dann nach weiterer Zeit ganz ausschalten. > > > > > > Aktwert[a] ist der Aktor, der gesteuert wird > > > Aktwert[a+1] ist der Funtkionswert. Im Detail: > > > 0-9 sind Funktionen rund um Jalousiesteuerung > > > 10-19 sind Funktionen zur Relaissteuerung > > > 20-29 sind Funktionen für Lichtdimmung. > > > Aktwert[a+2] ist ein Parameter ( Wie weit sollen Jalousien fahren, wie hell das Dimmlicht usw.) > > > Aktzeit ist die Zeit in ms, die vergehen soll, bis die Aktwert-Funktion erneut aufgerufen wird. > > > > > > Aktwert[a], Aktwert[a+1] und Aktwert[a+2] werden in einer anderen Funktion befüllt. > > > Nach deren Befüllung wir das Aktflag auf 1 gesetzt, damit folgender Thread aktiv wird: > > > > > > > > > Hallo. > > > > Das mit dem system.timer() als 32bit long Variable gefällt mir auch nicht so. > > 32bit entsprechen rund 4Mrd. Millisekunden, also ca. 71500 Minuten oder 1193 Stunden oder 49,7 Tage. > > Für eine absolute Zeit ist das zu wenig. > > Sofern system.timer() bei Null startet (wobei ich mir nicht sicher bin) gibt es dann nach knapp 50 Tagen einen Overflow. > > Zeitvergleiche mit system.timer() werden also kompliziert, weil man den Overflow berücksichtigen muss. > > Und wenn - wie ich glaube - Werte größer 2^31 als Negativ (2er-Komplement) interpretiert werden, dann wird es noch schwieriger. > > > > Ich habe in meiner Anwendung vor, ein Zeitraster von 128ms zu verwenden und die TimerTicks in einer separaten Variable zählen. > > Damit kann ich meine Schaltvorgänge ausreichend gut bedienen. > > > > In Deiner Anwendung wird beim Overflow von 'wart' der system.timer() eine Zeit lang immer größer sein. > > Oder aber - 2er-Komplement angenommen - 'wart' oder 'system.timer()' oder 'Aktzeit[x]' wird, > > obwohl es größer werden sollte, dummerweise als Negativwert interpretiert. > > Wann der compiler was macht, kann ich auch nicht sagen - das ist im Handbuch sehr schwammig formuliert. > > > > Für Deinen Zweck würde ich eine andere Vorgehensweise vorschlagen: > > - Berechnung der Wartedauer anstatt der Zielzeit > > - Speichern von Relativzeiten > > - Merken des letzten system.timer()-Standes > > - Berechnen der Timer-Differenz > > > > thread Ueberwachung > > { > > int a,wert; > > <b> > > long wart; // wart ist jetzt die Zeitdauer, nach der reagiert werden soll. > > long systimer_neu // zum Zwischenspeichern von system.timer() > > long systimer_alt // Reagiert wird, wenn (system.timer_neu - system_timer_alt) > > // größer als 'wart' wird. > > long systimer_diff // zum Zwischenspeichern von (system.timer_neu - system_timer_alt) > > </b> > > a=0; > > > > <b> > > do > > ( > > system_timer_neu = system.timer(); > > long systimer_diff = (long systimer_neu - long systimer_alt) & 0x7FFFFFFF; //Timer-Differenz > > // weg mit Negativ-Werten durch Veroderung > > } > > while (system.timer_diff >= wart) or Aktflag); // Solange wart-ezeit noch nicht abgelaufen. > > system_timer_alt = system.timer_neu; // neuen Timer-Wert Speichern > > wart = 3600000; // jede Stunde zumindest ein Lauf. > > </b> > > Aktflag=0; // Interuptflag zurücknehmen. > > > > while Aktwert[a]!= ENDE // Schleife durchführen > > { > > if Aktwert[a] == LEER // Wenn Aktwert[a]==LEER und nächster Eintrag > > { // ist ENDE, wir das ENDE um einen Eintrag > > if Aktwert[a+3]==ENDE Aktwert[a]=ENDE; // vorgeholt. > > } > > else > > <b> > > Aktzeit[a] = Aktzeit[a] - system.timer_diff // wartezeit um vergangene Zeit reduzieren > > if (Aktzeit[a] <= 0) // Ist diese Wartezeit abgelaufen? > > //allerdings bin ich hier nicht sicher, ob Negativwerte <0 unterstützt werden > > //es wird ja die Aktzeit[] wohl ein long sein, oder? > > </b> > > { > > if Aktwert[a+1] < 10 // Jalousien steuern > > { > > if Aktwert[a+1] == 0 // Modus 0 = Jalousie hoch bis Endschalter > > { > > dwmodule.JalAbs(JalZi[Aktwert[a]],Auf); // Jalousie hochfahren > > sleep 100; > > <b> > > Aktzeit[a] = 30000; // neue Wartezeit = 30 Sec > > </b> > > Aktwert[a+1]=1; // Modus auf 1 hochsetzen > > } > > else if Aktwert[a+1] == 1 // Modus 1 = Jalousien runterfahren. > > { > > if Aktwert[a+2] dwmodule.JalAbs(JalZi[Aktwert[a]],Ab); // Jalousie runterfahren, wenn angegeben. > > sleep 100; // verhindert das Kleben der Relais > > </b> > > if Aktwert[a+2] == 1 Aktzeit[a] = 4000; // Jalousie viertel runterfahren > > else if Aktwert[a+2] == 2 Aktzeit[a] = 8000; // Jalousie halb runter > > else if Aktwert[a+2] == 3 Aktzeit[a] = 12000; // Jalousie ganz runter > > else if Aktwert[a+2] == 4 Aktzeit[a] = 21000; // Jalousie ganz runter > > </b> > > Aktwert[a+1]=2; // Modi auf 2 hochsetzen > > } > > else if Aktwert[a+1] == 2 // Jalousien stoppen > > { > > dwmodule.JalAbs(JalZi[Aktwert[a]],Stop); > > sleep 100; > > Aktwert[a]=LEER; // Auftrag aus Aktwert löschen. > > } > > } > > else if Aktwert[a+1] < 20 // Relais steuern > > { > > } > > else if Aktwert[a+1] < 30 // Dimmer steuern > > { > > } > > } > > if (wart-Aktzeit[a]) > 0 wart=Aktzeit[a]; // die kürzeste Wartzeit in wart eintragen > > a=a+3; // nächsten Aktwert Eintrag prüfen. > > } > > } > > Danke für die Antwort. > > Ich werde das am Wochenende mal so umsetzen und dann nochmal Feedback geben. > Grundsätzlich hatte schon den Gedanken ohne den system.timer() zu arbeiten. Schon allein, > weil die Umlaufzyklen mit 20-50 Tagen jeden vernünftigen Test der Software unmöglich machen. > > Viele Grüße > > Detlef >