Logik Fehleingaben Timer abfangen

Morning :slight_smile:
Nach Anregung durch dieses Projekt

plane ich mir einen Zeitschaltuhr zu basteln (ESP8266 mit 1 Channel Relais Onboard).

Nun grüble ich über die Logik, wie man bei der Eingabe der Timer möglichst viele Fehleingaben abfangen kann.

struct Timer {
  bool active;      // is the timer running
  byte startMM;     // start minute
  byte finishMM;    // finish minute
} timer[5];

Die Timer sollen im Bereich von 0-59 Minuten liegen.
Das könnte man schon bei der Eingabe zum Beispiel über ein Webinterface festlegen im HTML.

Zwischen startMM und finishMM muss mindestens 1 Min liegen.

Die Abfrage auf Fehler müsste natürlich nur stattfinden wenn active == true

Aber wie frage ich die 5 Timer gegeneinander ab, ob sie sich zum Beispiel nicht überlagern?
Man könnte ja zum Beispiel Timer 4 benutzen und dann auf die Idee kommen, auch Timer 1 zu benutzen.
Das wäre natürlich super wenn es so universell ginge:
Ein Timer muss immer in einem freien Bereich liegen, der groß genug für seinen Anfang und Ende ist.

Einfacher ist vermute ich, erst Timer 1 zu belegen, dann wenn gewünscht Timer 2, dann 3….
So könnte man den letzten Timer immer auf die vorherigen abfragen.

Ich habe keine Ahnung wie man das logisch in IF oder switch case Abfragen packen könnte :grimacing:

Hat da jemand eine Idee dazu wie man das machen könnte?
Danke euch mal wieder :slight_smile:

a) ich vermute es ist einfacher, du nimmst statt der finishMM ein "durance" wo du die Laufzeit des Timers in Minuten einträgst. Weil vieleicht willst du einen Timer in Minute 50 starten lassen und 20 Minuten laufen lassen.

b) zum prüfen würde ich eine Funktion "check(size_t actual)" schreiben. In actual übergibst du den index des Timers der geprüft werden soll. Im Check arbeitest du dann in einer Forschleife alle anderen timer ab, und vergleichst ob sie mit actual nicht in konflikt stehen. Beim ersten Konflikt brichst du ab und meldest NOK zurück, wenn alle OK sind - OK.

c) Vergleich mit einem andern Timer:
start muss > als Ende sein oder Ende muss < als Start sein
wenn die (ermittelte) Endzeit > 59 ist musst ein wenig an der Logik feilen ... und so tun als wäre die eben ermittelte Endzeit - 60

d) auch musst dir was überlegen wie du mit "gelöschten" Timer umgehen willst.

Anregungen zu Schaltuhren findest du auch auf fips Seite.

Danke euch!

Ich würde schon gern von / bis haben bei den Timern, da ich es übersichtlicher finde in der Tabelle mit 5 Timern.

Ich würde die Timer über einen Radiobutton zum Beispiel einschaltbar machen.

Eine Funktion bekomme ich hin (auch mit Parameterübergabe denke ich )
Aber mir fehlt dann wie ich die Timer in der Schleife vergleiche gegeneinander:


if (timer[i].aktive) {

}

Ich werde mal etwas rumpuzzeln

pseudo

void check(byte actual)
for (size_t i = 0; i< anzahltimer; i++)
{
  if (i != actual)   // nur mit anderen vergleichen
    if (timer[actual].startMM < timer[i].finishMM) schlecht=true; 
 }

Soll klar sein, dass das nicht ausreicht.

Zeichne dir mal auf einem Zeitstrahl / 1h vier Timer auf und versuche die ifs für die Anlage eines 5ten Timers zu schreiben.
Was wie wo verundet/verodert werden muss

Viel Spaß ^^

Danke für die Idee :slight_smile:

Meinst Du es so, dass wenn ich z.B. einen Timer als active markiere und es per Tastendruck oder Klick auf Speichern im Webinterface bestätige, diesen Timerindex an die Funktion übergebe?

Was passiert aber, wenn man 3 Timer auswählt und gleichzeitig „scharf schaltet“?

Dann müsste ich die doch irgendwie nacheinander übergeben :thinking:

Oder bei Bestätigung alle mit einer Schleife durchlaufen lassen?

mit einer Schleife einen nach dem anderen prüfen und wenn ok dazu geben.

Ich habe mal etwas gemalt und überlegt :grimacing: :grin:

Angenommen

Timer1 startMM = 7
Timer1 finishMM = 13

Für die folgenden Timer dann

timer[i].startMM > timer1.finishMM && timer[i].finishMM > timer1.finishMM + 1
|| (oder)
timer[i].finishMM < timer1.startMM && timer[i].startMM < timer1.startMM - 1

Klingt das soweit logisch?

Danke euch :slight_smile:

ich sehe dein Bild nicht.
Aber so in etwa wirst hinkommen.

Was ich mir an deiner Stelle ganz genau ansehen würden: bei timer1.startMM = 0 wird es wegen deinem -1 möglicherweise Kaboom machen.

Ich denke jetzt ist der nächste Schritt dran: Mach dir einen Testsketch und probiers aus :wink:

Gut gesehen :slight_smile: Vermutlich weil byte nicht negativ werden darf?

Dann vorher noch ein


IF

timer[i].startMM == timer1.startMM || timer[i].finishMM == timer1.finishMM 

-> FEHLER 

Else

timer[i].startMM > timer1.finishMM && timer[i].finishMM > timer1.finishMM + 1
|| (oder)
timer[i].finishMM < timer1.startMM && timer[i].startMM < timer1.startMM - 1

evtl. hilft es statt byte ein int8_t zu machen, dann hast einen definierten (negativen) Wert und der vergleich könnte klappen ... (oder er wirft dir das nächste Warning).

Weiter geraten: statt einem -1 "hinten" könntest vermutlich auch ein +1 "vorne" machen ... ob 59, 60 oder 61 ist vermutlich für deine Vergleiche egal.

Hab ich schon dazu geraten einen Prototypen zu schreiben und es auszuprobieren?

Danke da hatte ich auch schon dran gedacht :slight_smile:
Ich werde es mal testen! :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.