Hallo,
Ich baue mir grade eine Schaltuhr nur leider funktioniert der Vergleich
nicht richtig.
Der vergleich funktioniert so lange das die Bis Ausschalt Stunde und Bis
Ausschalt Minute immer grösser sind als Ab Ausschalt Stunde und Ab
Ausschalt Minute.
Das geht
15:25 - 18:55
Das geht nicht
15:25 - 01:15
Vielleicht könnte mir da einer weiter helfen was hier falsch mache.
Bernd schrieb:> Der vergleich funktioniert so lange das die Bis Ausschalt Stunde und Bis> Ausschalt Minute immer grösser sind als Ab Ausschalt Stunde und Ab> Ausschalt Minute.
Wenn dein Programm auch so aussieht, sehe ich schwary.
Du kannst auch einfach die Stunden mit 100 erweitern und die Minuten
dazuzählen (wenn du die Stunden mit 60 multiplizierst, bekommst du
Sekunden heraus..).
Dann einfach zwei Werte vergleichen.
Bernd schrieb:> Das geht nicht> 15:25 - 01:15
Dafür brauchst du eine weitere Stelle ("Tag").
Bernd schrieb:> Das geht nicht> 15:25 - 01:15
Was auch immer da "gehen" sollte ...
In einem Fahrplan würdest du an der Stelle einen Verweis auf eine
Fußnote "Ankunft am nächsten Tag" finden.
Füge zur "Bis Zeit" 24h hinzu, vielleicht geht es dann.
Beitrag "Zeitvergleich zweier "Uhrzeiten""
zeigt das Prinzip.
Beide Uhrzeiten umrechnen in Minuten. Wenn BIS < AKT oder AKT < BIS
weiter laufen lassen. Wenn BIS == AKT -> Ziel erreicht.
Setzt natürlich voraus, dass Du in Intervallen < 1 Minute vergleichst.
Bernd schrieb:> Vielleicht könnte mir da einer weiter helfen was hier falsch mache.
Tja, so ist das eben mit Dingen, die zeitzyklisch geschehen sollen.
Im Grunde mußt du Buch führen über Ereignisse, die zu vorgebbaren Zeiten
geschehen sollen.
Dazu brauchst du erstmal ne Systemuhr. Wenn diese die Mitternacht
erreicht, also von 23.59 Uhr auf 00.00 Uhr, dann mußt du bei allen
deinen Ereignis-Merkern das Flag "ist abgehakt" löschen und dann deine
Liste durchsehen.
Etwa so im Prinzip:
1
item=record
2
sollzeit:longint;
3
event:deinEventTyp;
4
erledigt:boolean;
5
end;
6
7
DeineTafel:array[1bissonstwo]ofitem:
8
9
// So und nun dein Uhr-Interrupt:
10
uhr_handler:
11
uhrzeit:=uhrzeit+1Minute
12
ifuhrzeit>23.59Uhr
13
thenbegin
14
uhrzeit:=00.00Uhr
15
fori:=1tosonstwodo
16
DeineTafel[i].erledigt:=false;
17
end
18
19
// und nun deine Zeitschaltuhr:
20
fori:=1tosonstwodo
21
begin
22
ifDeineTafel[i].sollzeit<=uhrzeit
23
and
24
DeineTafel[i].erledigt=false
25
thenbegin
26
DeineTafel[i].erledigt:=true
27
Wirf_In_Queue(DeineTafel[i].event)
28
end
29
end;
30
uhr_handler_ende;
so einfach geht sowas (eigentlich...). Ich hab hier mal angenommen, daß
dieser Uhr-Handler alle Minute einmal gestartet wird. Und was du mit den
Events in der als vorhanden angenommenen Event-Queue machst, ist deine
Sache.
W.S.
Du hast nun das Problem, dass man auch bei Indizes für ringbuffer hat.
1) lege fest, was passieren soll, wenn aus == ein (ist dann 24h aus oder
ein?
2) unterscheide aus > ein (einfach, wie bisher)else (dann an bis
Mitternacht und ggf. ab Mitternacht).
Je nach Antwort 1 wird aus dem > ein >=.
Alternative für den Else Zweig: vertausche die Aktion:
On = Zeit>=an && Zeit<aus;
Wenn an>aus dann On=!On
A. S. schrieb:> Du hast nun das Problem, dass man auch bei Indizes für ringbuffer hat.
Er hat das Problem, dass man mit "Stunden und Minuten"-Vergleichen
entweder ein Riesen-Konstrukt aufbaut oder einfach nur mit Minuten
rechnet. Das letztere ist sinnvoll.
In der Regel prüfen Schaltuhren nur auf Gleichheit. Bei der
Einschaltzeit wird eingeschaltet, bei der Ausschaltzeit aus. Dazwischen
passiert nichts.
Schmeiß also die >, < einfach raus.
Peter D. schrieb:> In der Regel prüfen Schaltuhren nur auf Gleichheit. Bei der> Einschaltzeit wird eingeschaltet, bei der Ausschaltzeit aus. Dazwischen> passiert nichts.>> Schmeiß also die >, < einfach raus.
Prima - noch einfacher :-) (stimmt, die > < Abfragen sind sinnlos und
man kann sich die Umrechnung in Minuten sparen)
W.S. schrieb:> Bernd schrieb:>> Vielleicht könnte mir da einer weiter helfen was hier falsch mache.>> Tja, so ist das eben mit Dingen, die zeitzyklisch geschehen sollen.
Richtig spannend wird das bei der Umstellung von Sommer- auf Winterzeit,
wenn es die Stunde von 02:00 bis 02:59 zwei mal gibt ;-)
Peter D. schrieb:> In der Regel prüfen Schaltuhren nur auf Gleichheit. Bei der> Einschaltzeit wird eingeschaltet, bei der Ausschaltzeit aus. Dazwischen> passiert nichts.
Das geht aber nur, wenn die rtcc nicht separat batterieversorgt ist. Und
weder schalt- noch Uhrzeit sich ändern.
Hugo H. schrieb:> Er hat das Problem, dass man mit "Stunden und Minuten"-Vergleichen> entweder ein Riesen-Konstrukt aufbau
Naja, das Problem hätte er genauso mit Minuten gehabt. Es wäre ihm da
nur eher aufgefallen. So braucht er halt 3 Vergleiche statt einem. Bzw
in Summe 9 statt 3, spart dafür 3 Umrechnungen in Minuten. Bei dem
Codefragment (switch_buffer) macht es allerdings wenig Sinn, darüber zu
diskutieren.
sid schrieb:> oooder>> man packt einfach alles in eine unix timestamp> und hat die nächsten paar Jahre Ruhe :D>> von 1574397863 bis 1574469863 .. done
War auch mein erster Gedanke. time_t daraus machen. Dann hat man eine
'handliche' Integer Zahl und braucht nur einen Vergleich. Man kann auch
Zeiten addieren, die Zeiträume vergleichen etc.
A. S. schrieb:> Das geht aber nur, wenn die rtcc nicht separat batterieversorgt ist. Und> weder schalt- noch Uhrzeit sich ändern.
Du kannst auch den MC puffern, der AVR zieht <1µA im Power-Down. Die RTC
weckt ihn dann kurz für den Vergleich auf.
Wenn der MC nicht gepuffert wird, geht es aber auch so:
Beitrag "Re: Zeitvergleich zweier "Uhrzeiten""
PittyJ schrieb:> War auch mein erster Gedanke. time_t daraus machen. Dann hat man eine> 'handliche' Integer Zahl und braucht nur einen Vergleich.
Will man täglich schalten, muß man vor dem Vergleich noch Modulo 86400
rechnen. Ein < oder > kann man dann aber auch nicht feststellen, nur ein
==.
Bernd schrieb:> funktionieren> tut das nicht
Du hast ja auch die >, < drin gelassen.
Was stört Dich an der einfachen Variante, nur auf Gleichheit zu testen?
Peter D. schrieb:>> Du hast ja auch die >, < drin gelassen.> Was stört Dich an der einfachen Variante, nur auf Gleichheit zu testen?
Ich würde gerne das in den Ausschalt Zeitraum nicht wieder eingeschaltet
werden soll.
Ausgeschaltet werden soll von:
15:22 - 02:30
Das in den IF-Vergleich zu schreiben das bekomm ich nicht umgesetzt.
So wie von Hugo vorgeschlagen auf Gleichheit zu testen funktioniert,
aber danach kann ich ja wieder einschalten.
Bernd schrieb:> Peter D. schrieb:>>>> Du hast ja auch die >, < drin gelassen.>> Was stört Dich an der einfachen Variante, nur auf Gleichheit zu testen?>> Ich würde gerne das in den Ausschalt Zeitraum nicht wieder eingeschaltet> werden soll.> Ausgeschaltet werden soll von:> 15:22 - 02:30>> Das in den IF-Vergleich zu schreiben das bekomm ich nicht umgesetzt.>
Es soll eher um 15:22 ausgeschaltet werden und um 02:30 (nächster Tag)
wieder eingeschaltet werden. Das sind separate Aktionen mit einfacher
Identität als Bedingung.
So machen das auch "echte" elektronische Schaltuhren, allerdings nicht
die mechanischen, die tatsächlich zwischen 15:33 und 02:30 den Schalter
auf "aus" halten. Die elektronischen würden, hätte man das nach 15:21
aktiviert, erst am Folgetag wie gewünscht funktionieren.
Sowas wird viel einfacher, wenn man modulo verwendet. Einfach alles mod
24*60 rechnen, und start zum Nullpunkt machen, dann kann man schauen, ob
mehr Zeit vergangen ist, als das Interval lang ist.
1
// For numbers 0 to 1440 (=24*60), 16 bits would have been enough, but I've used 32 here for the people who are going to forget to increase it later when they add seconds, or upgread to yearly intervals, or do similar things.
2
uint_least32_tnow=(now_h*60+now_m)%(24*60);
3
uint_least32_tstart=(start_h*60+start_m)%(24*60);
4
uint_least32_tend=(end_h*60+end_m)%(24*60);
5
6
// check if now is in interval [start, end), with now, start and end being in (mod 24*60)
7
// 24*60 was added to prevent underflows, uint_least32_t has a moduli for underflows which is not a multiple of 24*60, which would otherwise lead to wrong results in that case.
Vorteil von Auswertung mit >= und < ist, dass man die Uhr (das Programm)
auch innerhalb eines Intervals starten kann und der Ausgang hat sofort
den korrekten Schaltzustand.
Bei "==" muss man unter Umständen warten bis entweder Ein- oder
Ausschaltpunkt erreicht wird, damit der Ausgang mit Sicherheit den
korrekten Zustand hat.
Z.B. die ZUD 132 von meiner Gasheizung schaltet nur bei Gleichheit um.
Je Ausgang sind bis zu 8 Ein-und Ausschaltzeiten programmierbar, die mit
Wochentagen verknüpft werden können.
Hat man die Uhrzeit oder Schaltzeiten geändert, kann man manuell
zwischen ein und aus umschalten.
Schaltuhren mit Bereichstest sind mir nicht bekannt.
Bernd schrieb:> So wie von Hugo vorgeschlagen auf Gleichheit zu testen funktioniert,> aber danach kann ich ja wieder einschalten.
Ich denke, das Programm soll das machen - was erzählst Du denn von "aber
danach kann ich ja wieder einschalten" ?
Bernd schrieb:> So wie von Hugo vorgeschlagen auf Gleichheit zu testen funktioniert,> aber danach kann ich ja wieder einschalten.
In der Regel ist es erwünscht, daß man die Uhr überstimmen kann und sei
es nur zu Testzwecken. Z.B. wenn der Schornsteinfeger die Abgasprüfungen
macht.
Peter D. schrieb:> In der Regel ist es erwünscht, daß man die Uhr überstimmen kann und sei> es nur zu Testzwecken.
Ja, also Ein/Aus/Auto, sollte schon zur Verfügung stehen.
Hugo H. schrieb:> Bernd schrieb:>> So wie von Hugo vorgeschlagen auf Gleichheit zu testen funktioniert,>> aber danach kann ich ja wieder einschalten.>> Ich denke, das Programm soll das machen - was erzählst Du denn von "aber> danach kann ich ja wieder einschalten" ?
Da geht dann auch mit "Ein/Aus/Auto", den gewünschten Zustand
herzustellen und sofort wieder auf Auto zu stellen. Dann vergisst man
das nicht und merkt es evtl. erst, wenn's bereits zu spät ist.