Hi, hab folgendes Problem (in C): Mir liegt aus dem AVR-Script folgender Code-Schnipsel vor: unsigned int var_array[MAX_VAR_ARRAY] = {12,30,19,15} unsigned char hh; unsigned char mm; unsigned char ss; .. }// Uhrzeit bestimmen hh = (time/3600)%24; mm = (time/60)%60; ss = time%60; .. var_array[0] // Beginn Stunde var_array[1] // Beginn Minute var_array[2] // Ende Stunde var_array[3] // Ende Minute Bisher war dann eben die if: if ( hh == var_array[0] && mm == var_array[1]) { // WEITERE BEDINGUNGEN // EIN } else { // AUS } if ( hh == var_array[2] && mm == var_array[3]) { // AUS } Die Schleifen werden alle 30 Sekunden gecheckt. Wenn nun mal Stromausfall war bzw. die "WEITEREN BEDINGUNGEN" sich innerhalb der Schaltzeit geändert haben, finden die so keine Berücksichtigung mehr. Ein einfaches: if ( hh >= var_array[0] && hh <= var_array[2] ) { ... } reicht natürlich nicht, da die Zeitspanne von 19:00 Uhr bis 6:00 Uhr so nicht erfasst werden kann. Nun hatte ich folgende Überlegung, die irgendwie Assi ist: Ist var_array[2] < var_array[0] { var_array[2] += 24; } Ist var_array[0] <= var_array[2] { ... dann müsste ich nur noch nachschauen, ob var_array[3] kleinergleich ist als mm. Geht das nicht irgendwie einfacher bzw. sinnvoller? Hab eben nur die Uhrzeit. mit mktime() in php zB. war das so schön easy.
und wie hat dir mktime bei dem problem weiter geholfen? aus mktime kommt doch auch bloss eine Zahl, diese hast du doch auf mit variable time.
Fall 1: $beginn = mktime(12,30,0,1,1,2000); // 12:30 Uhr $ende = mktime(19,15,0,1,1,2000); // 19:15 Uhr if ($beginn <= $ende) { } Fall 2 (über Mitternacht rüber): $beginn = mktime(18,0,0,1,1,2000); // 18:00 Uhr $ende = mktime(6,0,0,1,2,2000); // 6:00 Uhr if ($beginn <= $ende) { } So
Der Grund liegt aber darin, daß das Datum da enthalten ist. Damit ergibt sich dein Problem ja gar nicht.
Ja, nur habe ich bei meinem Code kein Datum dabei sondern nur die beiden Uhrezeiten ANFANG und ENDE sowie die JETZT-Zeit. Jemand eine Idee dazu?
Na, rufe mktime mit dem Datum von heute und den gewünschten End- und Anfangszeiten auf.
Dazu fehlt mir die lib. Habs nun mit einer if-Anweisung gelöst, die +24 auf die Variable rauf schlägt, wenns über Mitternacht geht.
Hier mal der Ansatz für diejenigen, die auch nur die Uhrzeit aber kein Datum dazu haben. Wenn einer eine bessere Idee hat, immer her damit! Danke an RoBue für die viele Arbeit, auf die ich zurück greifen konnte! Sinn der Übung ist wie bereits geschrieben, Code zu haben, der auch nach Stromausfall oder Werteänderung funktioniert. Diese Funktion ist bei RoBue "nur" als minutengenauer Vergleich enthalten. Mit unten aufgeführtem Code kann ich nun Tagestemperaturen variabel zeitabhängig schalten. // Uhrzeit bestimmen hh = (time/3600)%24; mm = (time/60)%60; ss = time%60; // Wenn es zwischen 0:00 Uhr und 1:00 Uhr ist, muss hh 24 werden if ( hh == 00 ) { hh = 24; } // PORTC0: // Temperatur: var_array[10] TWert = var_array[10]*10; // Über Temperatur und Sensor für Fenster: var_array[10] - Sensor0 - PORTA0 // Wenn der Zeitraum über Mitternacht geht, addiere zur Endzeit 24 // So wird zB. aus 3:00 Uhr 27:00 Uhr und ist damit mathematisch vergleichbar if ( var_array[20] < var_array[18] ) { var_array[20] += 24; } if ( hh >= var_array[18] && hh <= var_array[20] ) { if ((hh < var_array[20]) || (hh == var_array[20] && mm < var_array[21])) { if ((PINA&0b00000001) == 0 ) { // PORTA0: Fenster geschlossen? if ( ow_array[0] < TWert ) { PORTC |= (1 << PC0); // ein } else { PORTC &= ~(1 << PC0); // aus } } else { PORTC &= ~(1 << PC0); // aus } } else { // Minuten- Check PORTC &= ~(1 << PC0); // aus } } else { // Stunden - Check PORTC &= ~(1 << PC0); // aus } // Zurücksetzen der Stunde der Endzeit if ( var_array[20] >= 24 ) { var_array[20] -= 24; } Andy
Ach und zum testen: http://medixx.homeip.net Fenster 6 und 7 sind permanent offen :) Kontakte nicht gebrückt. Sensoren sind nur 1, 2 und 3 angeschlossen. Die anderen kommen erst diese Woche. Port C7 ist eine reine Schaltzeituhr. Aufbau ist wie auf dem Bild :)
Ich hab das Problem ehrlich gesagt immer noch nicht verstanden. 2 Zeitpunkte (ohne Datum) lassen sich grundsätzlich so nicht vergleichen. Da kannst nur feststellen ob ein bestimmter Zeitpunkt in einem Zeitintervall liegt. Dazu brauchst du eine Konvention, nämlich dass der 2. Zeitpunkt des Intervalls grundsätzlich immer später als der 1. Zeitpunkt des Intervalls ist, auch wenn er numerisch zunächst kleiner ist. Beim Intervall 23:00 - 6:00 ist 6:00 später als 23:00, obwohl die Stundenzahl kleiner ist. Dazu ist es hilfreich sich erst mal alle Zeitpunkte in Anzahl der Minuten seit Mitternacht umzuwandeln. Jetzt muss man nur noch berücksichtigen, ob das Intervall über Mitternacht läuft oder nicht. Hat man kein zusätzliches Mitternacht zu berücksichtigen, ist die Sache einfach. Der zu untersuchende Zeitpunkt muss größer als Intervall-Start und kleiner als Intervall-Ende sein. Hat man im Intervall Mitternacht mit drinnen, dann liegt der gesuchte Zeitpunkt im Intervall, wenn sein Minutenwert kleiner als der originale Intervall-Ende oder größer als Intervall-Start ist.
1 | test = stunden_test * 60 + minuten_test // zu testender Zeitpunkt |
2 | |
3 | start = stunden1 * 60 + minuten1 // Startzeit des Intervalls |
4 | ende = stunden2 * 60 + minuten2 // Endzeit des Intervalls |
5 | |
6 | if( ende < start ) |
7 | inside = ( ( test < ende ) || ( test > start ) ) |
8 | else
|
9 | inside = ( ( test > start ) && ( test < ende ) ) |
10 | |
11 | return inside |
Warnung: ungetesteter Code
Kann mir bitte jemand sagen, welchen Wert "inside" hier annehmen kann? mein Code: hh = (time/3600)%24; mm = (time/60)%60; jetzt = hh * 60 + mm; start = var_array[18] * 60 + var_array[19]; ende = var_array[20] * 60 + var_array[21]; if ( ende < start ) inside = ( ( jetzt < ende ) || ( jetzt >= start ) ); else inside = ( ( jetzt >= start ) && ( jetzt < ende ) ); if(inside) { .... } else { ... } Wenn ich ein: return inside; am Ende einfüge, hängt sich das Script auf. Bin noch totaler Anfänger in C. Pascal ist auch schon etwas her... Liegt es daran, dass das script zu bestimmten Zeitpunkten KEINEN Wert zurück gibt: Startzeit: 5:00 Uhr Ende 18:00 Uhr JETZT: 21:42 Uhr
Was spricht denn gegen die Brute Force Methode? Einfach nach dem Stromausfall 24h abziehen und dann alle 1440min bis zur aktuellen Zeit vergleichen. Selbst bei 100 Schaltzeiten ist das in weit unter 1s erledigt.
1 | if( stromausfall ){ |
2 | uint16t i; |
3 | for( i = 1440; i; i-- ) |
4 | vergleich( time_min - i ); |
5 | }
|
Peter
Hab meinen Fehler gefunden. unsigned char jetzt; unsigned char start; unsigned char ende; unsigned char inside; nun ist es so: unsigned int jetzt; unsigned int start; unsigned int ende; unsigned char inside; und funzt. Muss jedoch lesen, obs da nicht einen besseren Typen als int gibt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.