Forum: Mikrocontroller und Digitale Elektronik Logikfehler in Tasterauswertung für Menue


von Amper (Gast)


Lesenswert?

Hallo Zusammen,

ich versuche gerade ein Menue zu Programmieren. Um in das Menue zu 
kommen soll eine Taste eine Secunde lang gedrückt werden. Danach soll 
mit jedem weiteren druck der Taste in den nächsten Menue Punkte 
gesprungen werden. Das klapt auch so weit sehr gut.
Allerdings soll wenn ich im lezten Menue Punkt bin mit einem weiteren 
Druck der Taste das Menue verlassen werden.
Leider spring ich dann immer zurück in den ersten Menuepunkt.
1
int menuePunkt = 0;
2
3
unsigned long timemils, timesec, timesecalt, menueDelay;
4
unsigned long timeMenueTaster1, timeMenueTaster2, timePlusTaster, timeMinusTaster;
5
6
bool statusMenueTaster, statusPlusTaster, statusMinusTaster;
7
bool statusMenue = false, statusPlus = false, statusMinus = false;
8
bool minusOn = false, plusOn = false, menueOn = false;
9
bool timerabgelaufen = false;
10
11
void loop () {  
12
  timemils = millis();
13
  
14
  //Start Tasterabfrage plus entprellung und Zeitverzögerung für Menue
15
  statusMenueTaster = digitalRead(menueTaster);
16
  statusPlusTaster  = digitalRead(plusTaster );
17
  statusMinusTaster = digitalRead(minusTaster);
18
19
20
  if(statusMenueTaster == LOW){
21
    if(timeMenueTaster1 < timemils && statusMenue == false){
22
      statusMenue = true;
23
      menueOn = true;
24
      if (menuePunkt==0){
25
        menueDelay = timeMenueTaster1+950;
26
      }
27
    }
28
  }else{
29
    timeMenueTaster1 = timemils+50;
30
    statusMenue = false;
31
  }
32
33
  if(statusMenue == true && menuePunkt == 0){
34
    if(menueDelay < timemils){
35
      menuePunkt = 1;
36
      menueOn = false;
37
    }
38
  }
39
  
40
  if(statusPlusTaster == LOW){
41
    if(timePlusTaster < timemils && statusPlus == false){
42
      statusPlus = true;
43
      plusOn= true;
44
    }
45
  }
46
  else{
47
    timePlusTaster = timemils+50;
48
    statusPlus = false;
49
  }
50
51
  if(statusMinusTaster == LOW){
52
    if(timeMinusTaster < timemils && statusMinus == false){
53
        statusMinus = true;
54
        minusOn = true;
55
      }
56
  }
57
  else{
58
    timeMinusTaster = timemils+50;
59
    statusMinus = false;
60
  }
61
  //Ende Tasterabfrage plus entprellung und Zeitverzögerung für Menue
62
63
  //Gehe durch das Menue.
64
  if (menuePunkt != 0 && menueOn){
65
    menueOn = false;
66
    menuePunkt++;
67
    }
68
69
  if (menuePunkt== 1){
70
      analogWrite(5 ,255 );
71
    } else if (menuePunkt== 2){
72
      analogWrite(6 ,255 );
73
    } else if (menuePunkt== 3){
74
      analogWrite(11 ,255 );
75
    } else if (menuePunkt== 4){
76
      analogWrite(5 ,0 );
77
      analogWrite(6 ,0 );
78
      analogWrite(11 ,0 );
79
      menuePunkt =0;
80
    }
81
}

Ich komm leider nicht drauf wo mein logischer Fehler liegt.

Danke schon mal für eure hilfe und noch mehr danke an die jenigen die es 
sich verkneifen können mich dumm anzumachen weil ich erst mal 
Programmierun lernen soll oder das der Code völliger mist ist oder, 
oder, oder...
Ist ja leider in nicht ganz unüblich hier.


bis dann und Danke
Amper

: Verschoben durch User
von grundschüler (Gast)


Lesenswert?

Ohne debuggen

z.B. per LCD, uart, notfalls LEDs ist das ganz schwierig, den Fehler zu 
finden.

Du kannst mal versuchen menuePunkt auf 255 zu setzen. Wenn dann 1 
addiert wird ist er bei 0.

von A. S. (Gast)


Lesenswert?

Du setzt doch menuPunkt hier auf 0
Amper schrieb:
> } else if (menuePunkt== 4){
>       analogWrite(5 ,0 );
>       analogWrite(6 ,0 );
>       analogWrite(11 ,0 );
>       menuePunkt =0;
>     }

und im nächsten Durchlauf auf 1
>  if(statusMenue == true && menuePunkt == 0){
>    if(menueDelay < timemils){
>      menuePunkt = 1;
>      menueOn = false;
>    }
>  }

von Amper (Gast)


Lesenswert?

Hallo Grunschüler,

ich hab die ganzen Serial.print `s rausgenommen da der Code sonst 
ziemlich durcheinander ist. Ein paar LED´s hab ich auch drann um sehen 
zu was der yC gerade so macht.

@Achim S. ja das hab ich auch gesehen ich brauch das (if(statusMenue == 
true && menuePunkt == 0){) aber um beim ersten Druchlauf überhaubt ins 
menue zu kommen.

Wenn ich jede menge Serial.print eingebaut habe kann ich sehen das ich 
den statusMenue wider auf false setzte bevor die abfrage kommt 
allerdings muss ich dazu den taster ziemlich schnell wider loslassen. 
Was keine Lösung ist.

von Amper (Gast)


Lesenswert?

Ich habs:

Ich hab noch eine Bool eingesetzt die gesetzt wird wenn ich das Menue 
verlasse und erst wider rückgesetzt wird wenn ich den Tasterloslasse.
Wahrscheinlich gibt es noch eine elegantere Lösung aber mir fällt gerade 
keine ein.
1
if(statusMenueTaster == LOW){
2
  if(timeMenueTaster1 < timemils && statusMenue == false){
3
    statusMenue = true;
4
    menueOn = true;
5
    if (menuePunkt==0){
6
      menueDelay = timeMenueTaster1+950;
7
    }
8
  }
9
}else{
10
  timeMenueTaster1 = timemils+50;
11
  statusMenue = false;
12
  menueEnde = false;
13
}
14
15
...
16
17
if(statusMenue == true && menuePunkt == 0 && menueEnde == false){
18
    if(menueDelay < timemils){
19
      menuePunkt = 1;
20
      menueOn = false;
21
    }
22
  }
23
24
...
25
26
if (menuePunkt== 1){
27
    analogWrite(5 ,255 );
28
  } else if (menuePunkt== 2){
29
    analogWrite(6 ,255 );
30
  } else if (menuePunkt== 3){
31
    analogWrite(11 ,255 );
32
  } else if (menuePunkt== 4){
33
    analogWrite(5 ,0 );
34
    analogWrite(6 ,0 );
35
    analogWrite(11 ,0 );
36
    menuePunkt =0;
37
    menueEnde = true;
38
}

von Amper (Gast)


Lesenswert?

Manchmal hilft es einfach über ein Problem zu Sprechen um weiter zu 
kommen.

Danke und Grüße
Amper

PS: Kann ich den Beitrag schließen? da erledigt!

von Peter D. (peda)


Lesenswert?

Amper schrieb:
> Ich hab noch eine Bool eingesetzt die gesetzt wird wenn ich das Menue
> verlasse und erst wider rückgesetzt wird wenn ich den Tasterloslasse.

Natürlich darf man nicht nur das Drücken auswerten, da man ja auf die 
Flanke reagieren will. Das Loslassen zu prüfen ist also essentiell.

Amper schrieb:
> Wahrscheinlich gibt es noch eine elegantere Lösung aber mir fällt gerade
> keine ein.

Tasten entprellen und Flanke erkennen braucht man sehr oft. Daher lohnt 
es sich, dafür eine extra Task zu implementieren, die dann nur noch die 
fertigen Ereignisse liefert.
Das macht dann auch die Auswertung in der Mainloop deutlich einfacher 
und übersichtlicher.

Z.B.:
Beitrag "Universelle Tastenabfrage"

von Amper (Gast)


Lesenswert?

Hallo Peter Dannegger,

vielen Dank für dein Hinweis, hat mir sehr geholfen.

Grüße

von grundschüler (Gast)


Lesenswert?

Ich hab auf Taster nahezu ganz verzichtet und mache Eingaben per 
ir-Fernbedienung. Einmal programmiert ist das universell einsetzbar. Nur 
ein Pin und nahezu unbegrenzte Möglichkeiten für Menus.

von Amper (Gast)


Lesenswert?

Wenn ich irgendwann mal fertig werde poste ich nen Bild von der Uhr, da 
passt ne Ferhnbedinung einfach nicht zu.
Aber ja hab ich bei meine Lichtsteuerung auch bietet auch mehr 
möglichkeiten wie drei Taster :)

bis dann

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
Noch kein Account? Hier anmelden.