Hallo, ich hab hier bei einem kleinen Testprojekt (Mikrocontroller in C programmiert) gerade eine Blockade. Meine Software kennt die aktuelle Uhrzeit. Außerdem ist bekannt wann das Gerät aktiv und wann inaktiv sein soll. Das Gerät schaltet sich einmal am Tag an und einmal aus. Jetzt muss ich herausfinden, ob ich mich gerade im Zustand "AN" oder "AUS" befinde. Mein erster Ansatz war eine Ansammlung an verschachtelten If-Abfragen. Das hat auch soweit funktioniert, sah aber sehr wüst und unverständlich aus. Imho ist das ja eher ein mathematisches Problem. Es muss doch eine kurze, elegante Lösung dafür geben. Ich habe noch eine weitere Bekannte, nämlich die "Endzeit", nämlich 23:59. Danach springt meine Zeit wieder auf 00:00. Wie ich diese Info mit in eine Formel einbaue weiß ich aber auch nicht. Kann mir jemand einen Denkanstoß geben? MFG, Karlo
Kannst Du Daten irgendwie persistent speichern? Dann würde ich eine Statusvariable (boolean) einführen. z.B. "is_running" Sobald AN stattfindet stellst Du die auf true. Bei AUS auf false. Dann kannst Du problemlos jederzeit mit: if (is_running) {...} else {...} Abfragen, ob's grade läuft...
Karlo schrieb: > Jetzt muss ich herausfinden, ob ich mich gerade im Zustand "AN" oder > "AUS" befinde. Wenn ich richtig verstehe willst Du anhand der Istzeit und der EIN-Zeit udn AUS-Zeit wissen, ob Du einen Ausgang ein- oder Ausschalten sollst. Denn für den Controller herauszufinden ob er selbst eingeschaltet ist oder ausgeschaltet ist ... :) Karlo schrieb: > Imho ist das ja eher ein mathematisches Problem. Es muss doch eine > kurze, elegante Lösung dafür geben. Was hälst Du davon, die Zeiten in eine "Sekundenzeit" (oder Minutenzeit) umzurechnen, die schön linear ist. 12:00:00 wäre dann 12*3600 = 43200. Brauchst Du dann 32bit dafür. Die Minuten gingen in 16 bit hinein. rgds
Achja, da du ja weist, wann es AN oder AUS sein sollte kannst Du auch ohne Persistenz diese Hilfevariable setzen: if (current_time => start_time && current_time <= end_time) { is_running = true; } else { is_running = false; } Das ganze geht, wenn du einen UNIX-Timestamp als int in current_time, start_time und end_time stehen hast. Ab dann immer if (is_running) abfragen...
Karlo schrieb: > Imho ist das ja eher ein mathematisches Problem. Es muss doch eine > kurze, elegante Lösung dafür geben. > Ich habe noch eine weitere Bekannte, nämlich die "Endzeit", nämlich > 23:59. Danach springt meine Zeit wieder auf 00:00. Gibt es auch. Wieviele Minuten sind seit Mitternacht vergangen? MinSinceMidnight = 60 * Stunde + Minuten; dsselbe für die Einschaltzeit und die Ausschaltzeit und schon hast du eine schöne lineare Zahl, die während des Tages von 0 bis 1339 anwächst und mit der du wunderbar gegen 2 Grenzwerte vergleichen kannst (aben die Einschalt bzw. Ausschaltzeit) vergleich kanns, ob die aktuelle Zeit zwischen diesen beiden liegt oder nicht. Liegt sie dazwischen, dann 'Gerät ein'. Liegt sie nicht dazwischen dann 'Gerät aus'. Wenn du nicht auf gemeinsame Minuten gehen willst, dann geht es fast genau so einfach. Du musst dir nur darüber im klaren sein, wann genau denn eine Zeit vor einer anderen liegt. Wenn die Stunden von A schon mal kleiner sind als die Stunden von B, dann liegt A vor B. Sind die beiden gleich, dann entscheiden die Minuten wer vorne liegt.
1 | if( actHour < onHour || ( actHour == onHour && actMin < onMin ) ) |
2 | TurnOff; |
3 | else if( actHour > offHour || ( actHour == offHour && actMin > offMin ) ) |
4 | TurnOff; |
5 | else
|
6 | TurnOn; |
Die Phase rund um Mitternacht hab ich jetzt noch nicht vollständig durchdacht, da es aber relativ selten vorkommt, dass man in dieser Zeit schalten muss, ignoriere ich diesen Sonderfall mal. D.h. wir tun so, dass man sich einen Tag hernimmt
1 | +------------------------------------------------+ |
2 | | | |
3 | Ein Aus |
Alles was zwischen Ein und Aus liegt ist die 'Gerät ist eingeschaltet' Zeit. Alles was nicht zwischen diesen beiden Zeitpunkten liegt ist 'Gerät aus'. Also das hier
1 | +------------------------------------------------+ |
2 | ###############| |############# |
3 | Ein Aus |
stellst du also fest, dass die aktuelle Zeit vor 'Ein' liegt, also im schraffierten Bereich ist, dann -> Gerät aus. Selbiges für den Fall, dass die aktuelle Zeit nach 'Aus' liegt. Und alles was dann noch übrig bleibt -> 'Gerät ein' Du kannst jetzt den nicht schraffierten Teil nach links oder rechts verschieben. Solange du dabei nicht über Mitternacht drüber kommst, gibt es da kein Problem.
Danke erstmal. Ich habe meine Zeit in Minuten seit Mitternacht vorliegen, was aber für die grundsätzliche Lösung weniger wichtig ist. Die letzten beiden hier genannten Vorschläge (current > ein && current < aus) haben imho beide einen Denkfehler: aus kann kleiner sein als ein. Bsp: ein= 21:00; current=22:00; aus=6:00 Schon klappt die obige Abfrage nicht mehr, denn eigentlich müsste ich jetzt"EIN" sein. Mit verschachtelten, hässlichen Abfragen lösbar. Aber wie gehts kürzer?
Karl Heinz Buchegger schrieb: > Du kannst jetzt den nicht schraffierten Teil nach links oder rechts > verschieben. Solange du dabei nicht über Mitternacht drüber kommst, gibt > es da kein Problem. > Kommst du über Mitternacht drüber
1 | +------------------------------------------------+ |
2 | |####################################| |
3 | Aus Ein |
dann drehen sich ein paar Sachen um. Die Skizze zeigt dir aber auch, wie man diesen Fall erkennen kann. Die Aus-Zeit ist kleiner als die Ein-Zeit (im Gegensatz zu oben). Und die Skizze sagt dir auch, wie du die Abfragen umdrehen musst, damit das Ergebnis wieder stimmt. Schon toll - so eine Skizze. Oder?
Karlo schrieb: > > Mit verschachtelten, hässlichen Abfragen lösbar. Aber wie gehts kürzer?
1 | turnOn = ( current > ein && current < aus ); |
2 | // wenn die Schaltzeit über Mitternacht drüber geht, dann dreht sich
|
3 | // alles um
|
4 | if( aus < ein ) |
5 | turnOn = !turnOn; |
was ist denn da verschachtelt und hässlich? Oder wenn du es lieber etwas expliziter magst
1 | if( aus < ein ) |
2 | turnOn = ( current < aus || current > ein ); // Mitternacht ist drinnen |
3 | else
|
4 | turnOn = ( current > ein && current < aus ); // Tagsüber |
oder noch etwas expliziter
1 | turnOn = FALSE; |
2 | |
3 | if( aus < ein ) // SChaltzeit geht über Mitternacht? |
4 | {
|
5 | if( current < aus || current > ein ) |
6 | turnOn = TRUE; |
7 | }
|
8 | else
|
9 | {
|
10 | if( current > ein && current < aus ) |
11 | turnOn = TRUE; |
12 | }
|
Eleganter als mit verschachtelten ifs geht es wohl nur noch, wenn man einen geeigneten Zahlentyp hat, der beim Rechnen auch um Mitternacht überläuft. Dann ist die Bedingung nämlich (current - ein) < (aus - ein). Aber der Aufwand, die Uhrzeiten entsprechend umzurechnen (oder die entsprechende Subtraktionsfunktion zu schreiben), ist wohl größer als die paar verschachtelten Verzweigungen.
Hallo, ich würde das etwas allgemeiner angehen, nämlich dass es mehr als je eine Ein- und Auszeit gibt. dann gehst du einfach die Liste der Schaltzeiten durch, die letzte, die noch kleiner ist als die aktuelle, bestimmt den Schaltzustand. Gruss Reinhard
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.