Arduino: Finde den Fehler im Sketch nicht, bitte um Hilfe!

Gast #5042217
Lesenswert?

Hi,

ich versuche ein Menü mit drei Tasten und einem Nokia 5110-Display zu 
schreiben, es funktioniert nocht nicht viel so wie es soll, aber das 
muss ich alles noch austüfteln, deswegen machen ich das auch, will mich 
mal an was komplexeres auf Anfänger-Niveau wagen.

Erstmal hier der letzte Versuch und danach die eigentliche Frage:
1
#include <SPI.h>
2
#include <Adafruit_GFX.h>
3
#include <Adafruit_PCD8544.h>
4

5
Adafruit_PCD8544 display = Adafruit_PCD8544(2, 3, 4, 5, 6);
6

7
const int btnPin = 0;
8
const int ledPin =  13;
9

10
const int btnUp = 1;
11
const int btnOk = 2;
12
const int btnDwn = 3;
13

14
const int btnUpL = 928;
15
const int btnUpH = 932;
16
const int btnOkL = 985;
17
const int btnOkH = 1005;
18
const int btnDwnL = 970;
19
const int btnDwnH = 980;
20

21
int ledState = HIGH;
22
int btnState;
23
int lBtnState = LOW;
24

25
long lDbncTime = 0;
26
long dbncDelay = 500;
27

28
//int subMenus = 1;
29

30
void setup() {
31

32
  pinMode(btnPin, INPUT);
33
  pinMode(ledPin, OUTPUT);
34

35
  Serial.begin(9600);
36
  display.begin();
37
  display.setContrast(45);
38
  display.setTextSize(1);
39
  display.setTextColor(BLACK);
40
  display.clearDisplay();
41

42
}
43

44
void loop() {
45
  buttons();
46
}
47

48
void buttons() {
49
  int btnData = analogRead(btnPin);
50
  Serial.println(btnData);
51
  int tmpBtnState = LOW;
52
  if (btnData > btnDwnL && btnData < btnDwnH) tmpBtnState = btnDwn;
53
  else if (btnData > btnOkL && btnData < btnOkH) tmpBtnState = btnOk;
54
  else if (btnData > btnUpL && btnData < btnUpH) tmpBtnState = btnUp;
55
  else tmpBtnState = LOW;
56
  if (tmpBtnState != lBtnState) lDbncTime = millis();
57
  if ((millis() - lDbncTime) > dbncDelay) btnState = tmpBtnState;
58
  lBtnState = tmpBtnState;
59

60
  display.setCursor(10, 10);
61
  display.println("Hauptbild");
62

63
  if (lBtnState == btnOk) mainMenu(1);
64

65
  display.display();
66
}
67

68
void mainMenu(int subMenus) {
69

70
  display.clearDisplay();
71

72
  //buttons();
73

74
  display.setCursor(2, 2);
75
  display.println("SubMenu1");
76
  display.setCursor(13, 2);
77
  display.println("SubMenu2");
78
  display.setCursor(24, 2);
79
  display.println("SubMenu3");
80
  display.setCursor(35, 2);
81
  display.println("Back");
82
  
83
  switch (subMenus) {
84

85
    case 1:
86
      display.clearDisplay();
87
      display.drawRect(0, 0, 84, 11, BLACK);
88
      if (btnState == btnOk) subMenu_0();
89
      break;
90

91
    case 2:
92
      display.clearDisplay();
93
      display.drawRect(0, 11, 84, 11, BLACK);
94
      //if (btnState = btnOk) subMenu_1();
95
      break;
96

97
    case 3:
98
      display.clearDisplay();
99
      display.drawRect(0, 22, 84, 11, BLACK);
100
      //if (btnState = btnOk) subMenu_2();
101
      break;
102

103
    case 4:
104
      display.clearDisplay();
105
      display.drawRect(0, 33, 84, 11, BLACK);
106
      if(lBtnState == btnOk) return;
107
      break;
108
  }
109

110
  switch (lBtnState) {
111

112
    case btnUp:
113
      subMenus = subMenus - 1;
114
      if (subMenus < 1) subMenus = 4;
115
      break;
116
    case btnDwn:
117
      subMenus = subMenus + 1;
118
      if (subMenus > 4) subMenus = 1;
119
      break;
120
  }
121

122
  display.display();
123
}
124

125
void subMenu_0() {
126

127
  display.clearDisplay();
128
  display.setCursor(2, 2);
129
  display.println("Ende!");
130

131
}

(Haupt)Problem: Die buttons-Funktion funktioniert ansich funktionell, 
auch durch die cases im switch(subMenus) zu blättern funktioniert, aber 
seltsamerweise nur solange sie im Loop stehen, das Aufrufen der 
mainMenu-Funktion geht von überall, aber sobald die Funktion läuft, 
passiert nichts beim Tastendruck. Wie man im Code sehen kann, habe ich 
die buttons-Funktion auch nochmal versucht in der mainMenu-Funktion zu 
starten, was theoretisch und praktisch keinen Sinn macht.
Könnt ihr den Fehler erkennen? Ich stehe total auf dem Schlauch.

Nebenproblem: Wenn das switch-statement im Loop ist und funktioniert, 
reagieren die Tasten viel zu schnell, ich kapier nicht wie ich das 
ausbremsen soll, hatte vor und nach dem Speichern vom temporären in den 
letzten Zustand eine Verzögerung eingebaut, aber das hat nicht 
funktioniert.

Ich würde mich sehr freuen, wenn ihr mich ein wenig unterstützen könnt, 
ich weiss, dass hier einige auf solche Fragen sehr allergisch reagieren, 
daher möchte ich extra erwähnen, dass es mir im Grunde reicht, wenn ihr 
mir die Fehler aufzeigt, bin aber klar nicht unglücklich, wenn ihr mir 
zumindest in ganz normalen Worten eine alternative Lösung anbietet.

Vielen Dank im Voraus,

Bastler
Gast #5042222
Lesenswert?

> Die buttons-Funktion funktioniert ansich funktionell,
> auch durch die cases im switch(subMenus) zu blättern funktioniert,
> aber seltsamerweise nur solange sie im Loop stehen, das Aufrufen der
> mainMenu-Funktion geht von überall, aber sobald die Funktion läuft,
> passiert nichts beim Tastendruck.

Kannst du dein Problem nochmal auf deutsch beschreiben? Das ist für mich 
total unverständlich. Versuche es mal mit viel kürzeren Sätzen.
Gast #5042245
Lesenswert?

Stefan U. schrieb:
> Kannst du dein Problem nochmal auf deutsch beschreiben? Das ist für mich
> total unverständlich. Versuche es mal mit viel kürzeren Sätzen.

Dafür sind doch die Kommas da, das ist halt das Problem. Wenn ich es im 
Kontext kürzer beschreiben könnte, würde ich das. Die buttons-Funktion 
funktioniert nur im loop, in jeder anderen Funktion nicht.

Flip B. schrieb:
> die fkt und alle abfragen in dieser funktion werden nur währen des
> drückens von ok ausgeführt.

Ne, lBtnState ist nachdem der Taster gedrückt wurde, die Funktion läuft 
dann, dabei wird aber immernoch "Hauptbild" angezeigt und darüber dann 
die Einträge aus der mainMenu-Funktion. Innerhalb der cases reagiert die 
Taste btnOk, aber auch sehr seltsam, wenn ich sie nur kurz drücke, dann 
ruft es die mainMenu-Funktion erneut auf, wenn ich sie länger halte, 
dann das, was im angewählten case steht, die subMenu_0-Funktion. Aber 
ich kann nicht mehr durch die cases switchen.

> Mal dir mal deine ganze verschachtelung auf.

Das habe ich vorher schon, sozusagen, also mir ein Schema aufgestellt, 
deswegen ja, für mich scheint es alles logisch, aber mein Verständnis 
dafür reicht wohl noch nicht aus, um zu erkennen warum.

> Trenne zwischen status, eingabenverarbeitung  und anzeige, alles muss
> regelmässig gemacht werden.

Das verstehe ich nicht.
Gast #5042255
Lesenswert?

Peter D. schrieb:
> Du brauchst eine Flankenerkennung, da Du ja nur eine Aktion bei
> jedem Drücken ausführen willst und nicht solange Du drückst.
> Und Entprellen ist auch sinnvoll.
> Es scheint, daß Du die Tasten analog mit Spannungsteiler einliest, hier
> mal ein Beispeil dafür:
> Beitrag "Tastenmatrix auslesen über nur 2 Leitungen"


Ja, es funktioniert ja nach demselben Prinzip, ein Widerstand hängt 
zwischen Gnd und I/O und zwischen +5V und den Taster-Eingängen jeweils 
einer mit anderem Wert, der Ausgang der Taster hängt wiederum auch am 
I/O bzw. Gnd über den ersten Widerstand. Ich habe doch ein btnState und 
l(ast)BtnState, also während und danach und der Sinn der 
buttons-Funktion ist doch Entprellen.

Dein verlinkter Beitrag ist mir noch zu hoch, soweit bin ich noch nicht, 
aber der Link dazu ist gespeichert, danke dafür.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren