Forum: Mikrocontroller und Digitale Elektronik Display Arduino


von Katrina N. (Gast)


Lesenswert?

Hey Leute,

ich steh gerade glaub ich mega auf dem Schlauch....
Mein Display ist zur Auswahl von Cocktails da. Ich habe bis jetzt 6 
Strings in denen verschiedene stehen. Jetzt soll über die Taster Down 
und Up alle angezeigt werden.
Ich dachte es mir so:
   case btnUP:
     {

     lcd.setCursor(0,0);
     lcd.print(myStrings[i]);
     i--;
     lcd.setCursor(0,1);
     lcd.print(myStrings[i]);
     i--;
     break;
     }
   case btnDOWN:
     {

    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i++;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;
    break;

     }



Nur leider zählt er beim zweiten nicht hoch und nicht runter.... er 
zeigt mir in der ersten Zeile String 1 an und in der 2. Zeile String 2, 
dass funktioniert.


Hat jemand eine Idee????



Vielen vielen Dank

von Hubert (Gast)


Lesenswert?

Probier mal lcd.clear(); vor der Cursorzuweisung.

von Katrina N. (Gast)


Lesenswert?

bringt leider nichts ...

von Katrina N. (Gast)


Lesenswert?

und warum braucht mein Display zweimal den RESET Button, wenn ich wieder 
zur Anfangsbedingung will?

von Mick (Gast)


Lesenswert?

Poste mal den ganzen Code - oder wenigstens die Deklaration von 
myStrings.

von Katrina N. (Gast)


Lesenswert?

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char* myStrings[]={"GinTonic        ", "JackyCola       ", "WodkaBull 
",
"WodkaLemon      ", "CaptainCola     ","Wasser          "};

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0,0);
  lcd.print("Cocktailwahl    ");

}

void loop() {
  int x;
  int i;
  x = analogRead (0);
  lcd.setCursor(0,0);
  if (x < 60) {
    lcd.print ("Abbruch         ");
  }
  else if (x < 200) {

    lcd.print ("GIN             ");
  }
  else if (x < 400) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i++;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;
   }

  else if (x < 600){

    lcd.print ("Bestaetigung    ");
  }
  else if (x < 800){

    lcd.print ("Welcome         ");
  }
}

von Carl D. (jcw2)


Lesenswert?

Und welche Hardware hält an "A0"?

von Mandi (Gast)


Lesenswert?

es sieht so aus, ohne den ganzen Code zu kennen, als ob nur
einmal btnDOWN bzw. btnUP angesprungen wird.
Der Fehler liegt wahrscheinlich in der Tastenabfrage oder
Aufruf des Unterprogramms.

  case btnUP:
    {
    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i--;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i--;
    if (i==0) i=6;  // Nach Menüpunkt 1 dann Menüpunkt 6
    break;
    }

  case btnDOWN:
    {
    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i++;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;
    if (i==7) i=1;   // Nach Menüpunkt 6 dann Menüpunkt 1
    break;
    }

von Hubert (Gast)


Lesenswert?

Katrina N. schrieb:
> else if (x < 400) {

Ich würde zusätzlich noch folgende Bedingung hinzufügen:

else if ((x<400) && (x>200)) {

Genauso natürlich auch bei den anderen Schleifen:

else if ((x<600) && (x>400)) {

else if ((x<800) && (x>600)) {

Ansonsten sind bei einem Wert von sagen wir mal x=500 die Bedingungen 
von 3 Schleifen erfüllt, ob dies gewünscht ist, ist fraglich.

von Katrina N. (Gast)


Lesenswert?

@Mandi

vielen Dank, das denke ich auch, dass es nur einmal aufgerufen wird.
Mit deiner Erweiterung funktioniert es jedoch auch noch nicht.


@Carl Drexler
an "A0" hängen die 1er Eingänge der Schalter UP, Right, Down

von Katrina N. (Gast)


Lesenswert?

Ja stimmt Hubert, diese Absicherung sollte ich auf jeden Fall machen.

von SloJo (Gast)


Lesenswert?

Hubert schrieb:
> Ich würde zusätzlich noch folgende Bedingung hinzufügen:
>
> else if ((x<400) && (x>200)) {

Die sind ueberfluessig und auch noch falsch, weil ein Wert von 200 nun 
gar keinem Bereich mehr zugeordnet ist.

von SloJo (Gast)


Lesenswert?

Katrina N. schrieb:
> Hat jemand eine Idee????

Ja, fang nochmal von vorne an:

 - Poste den aktuellen, kompletten Sourcecode und nicht Fragmente aus 
verschiedenen Ansaetzen.
 - Erklaere genau, was die Anforderungen sind und wie die Loesung 
funktionieren soll.
 - Erklaere genau, wie du testest und was dabei passiert.

Haeltst du dich daran, kann man dir helfen. Aber wahrscheinlich findest 
du das Problem dann sogar selbst.

von doedel (Gast)


Lesenswert?

Du darfst die i Variable nicht innerhalb von Loop deklarieren. Die wird 
logischerweise sonst bei jedem Schleifendurchlauf wieder auf 0 gesetzt.

von Loddaar (Gast)


Lesenswert?

i ist eine lokale Variable, du willst aber eine globale

du solltest auch die Warnungen des Compilers nicht ignorieren

von Katrina N. (Gast)


Lesenswert?

Alles klar also nochmal von Anfang an:
hier mein aktueller Code für das Display mit Ansteuerung vom Arduino 
Mega:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char* myStrings[]={"GinTonic        ", "JackyCola       ", "WodkaBull 
",
"WodkaLemon      ", "CaptainCola     ","Wasser          "};

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0,0);
  lcd.print("Cocktailwahl    ");

}

void loop() {
  int x;
  int i;
  x = analogRead (0);
  lcd.setCursor(0,0);
  if (x < 60) {
     lcd.clear();
    lcd.print ("Abbruch         ");
  }
  else if (x < 200) {
     lcd.clear();
    lcd.print ("GIN             ");
  }
  else if (x < 400) {

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i++;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;
    if (i==7) i=1;
   }

 else if (x < 600) {
    lcd.clear();
    lcd.print ("Bestaetigung    ");
  }
  else if (x < 800) {
   lcd.clear();
    lcd.print ("Welcome         ");
  }
}



Ziel ist:

Eine Auswahl von Cocktails, die auf meinem 16*2 Display mit den Buttons 
Up and Down angezeigt werden sollen.

Problem:
Laden funktioniert, die Buttons Right, Left, Up und Select 
funktionieren.
Bei Down zeigt er mir aktuelle nur den String 1 in Zeile 1 an und String 
2 in Zeile 2 bei erneutem rücken von Down sollte eigentlich dann String 
3 in Zeile 1 und String 4 in Zeile 2 stehen.


Vielen Dank schon mal

von Katrina N. (Gast)


Lesenswert?

Der Compiler zeigt keine Warnungen an. Habe das i jetzt als globale 
gesetzt, jetzt hängt sich das Display nach betätigen von Button Down 
auf.

von Mark B. (markbrandis)


Lesenswert?

Du hast die Variable i zwar angelegt, aber nicht initialisiert. Damit 
ist ihr Wert unbestimmt (wenn es eine lokale Variable ist). Das passt so 
nicht.

Als globale Variable sollte ihr Initialwert laut C-Standard gleich Null 
sein, wenn man keine explizite Zuweisung vornimmt. Trotzdem ist es 
besser wenn man einen sinnvollen Startwert hinschreibt. Zumal als 
Anfänger(in) sollte man sich das angewöhnen :-)

: Bearbeitet durch User
von Katrina N. (Gast)


Lesenswert?

Ja das ist mir schon klar mit der 0, die ist auch da gewesen.

von Mark B. (markbrandis)


Lesenswert?

Katrina N. schrieb:
> Ja das ist mir schon klar mit der 0, die ist auch da gewesen.

Dann postest Du also nicht den Code, der aktuell bei Dir läuft. Somit 
ist es sinnlos Dir helfen zu wollen. Schade auch. :-(

von Katrina N. (Gast)


Lesenswert?

Naja doch schon, habe nach dem geschrieben wurde, dass ich es als lokale 
Variable deklariert, es als globale, mit int i = 0, geändert.

von Katrina N. (Gast)


Lesenswert?

das ist jetzt der aktuelle:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char* myStrings[]={"GinTonic        ", "JackyCola       ", "WodkaBull 
",
"WodkaLemon      ", "CaptainCola     ","Wasser          "};
int i=0;
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0,0);
  lcd.print("Cocktailwahl    ");

}

void loop() {
  int x;

  x = analogRead (0);
  lcd.setCursor(0,0);
  if (x < 60) {
     lcd.clear();
    lcd.print ("Abbruch         ");
  }
  else if (x < 200) {
     lcd.clear();
    lcd.print ("GIN             ");
  }
  else if (x < 400) {

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i++;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;
    if (i==7) i=1;
   }

 else if (x < 600) {
    lcd.clear();
    lcd.print ("Bestaetigung    ");
  }
  else if (x < 800) {
   lcd.clear();
    lcd.print ("Welcome         ");
  }
}

von Heiko G. (Gast)


Lesenswert?

Ich würde erstmal das Ergebnis von analogRead ausgeben, um 
sicherzustellen das die A/D-Wandlung die erwarteten Werte liefert.

Weiter wird im Bereich x zwischen 200 und 400 die variable I so schnell 
inkrementiert wie die Loop()-Funktion aufgerufen wird, so das beim 
loslassen dann eigentlich nur ein zufälliger Wert in I steht. Vermutlich 
soll doch bei jedem Betätigen die Variable I nur einmal weitergestellt 
werden.

Was gibt analogRead zurück wenn keine Taste betätigt wird ?

Da nur 6 Strings im Array sind werden diese von 0 .. 5 indiziert. Daher 
muss es

if (i==6) i=0;

heissen

von Katrina N. (Gast)


Lesenswert?

Heiko G. schrieb:
> Was gibt analogRead zurück wenn keine Taste betätigt wird ?

hier gibt er 1023 aus

von Katrina N. (Gast)


Lesenswert?

Ja bei betätigen soll i nur einmal weitergestellt werden

von Hubert (Gast)


Lesenswert?

SloJo schrieb:
> else if ((x<400) && (x>200)) {

Richtig, es muss wie folgt heißen: else if ((x<400) && (x>=200)) {

Jedoch musst du mir noch erklären, warum es deiner Meinung nach nicht 
gebraucht wird.

von Mandi (Gast)


Lesenswert?

zum testen:
1
// mit Arduino-Monitor Ausgabe
2
// include the library code:
3
#include <LiquidCrystal.h>
4
5
// initialize the library with the numbers of the interface pins
6
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
7
8
int i = 0;
9
10
char* myStrings[]={
11
 "GinTonic        ",
12
 "JackyCola       ",
13
 "WodkaBull       ",
14
 "WodkaLemon      ",
15
 "CaptainCola     ",
16
 "Wasser          "};
17
18
void setup() {
19
  Serial.begin(9600);
20
  for (i = 0; i < 6; i++){
21
    Serial.println(myStrings[i]);  // für Testzwecke
22
    delay(1);
23
  }
24
25
    // set up the LCD's number of columns and rows:
26
  lcd.begin(16, 2);
27
    // Print a message to the LCD.
28
  lcd.setCursor(0,0);
29
  lcd.print("Cocktailwahl:   ");
30
  }
31
32
void loop() {
33
34
  int x=0;                         // evtl. x=1023
35
  x = analogRead (0);
36
37
  if (x > 0) && (x < 61) {         //  1-60
38
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
39
    lcd.clear();
40
    lcd.print ("Abbruch         ");
41
  }
42
43
  else if (x > 60) && (x < 201) {  // 61-200
44
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
45
    lcd.clear();
46
    lcd.print ("GIN             ");
47
  }
48
49
  else if (x > 200) && (x < 401) { // 201-400
50
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
51
    lcd.clear();
52
    lcd.setCursor(0,0);
53
    lcd.print(myStrings[i]);
54
    i++;
55
    lcd.setCursor(0,1);
56
    lcd.print(myStrings[i]);
57
    i++;
58
    if (i==6) i=0;                 // Index 0 für GinTonic
59
   }
60
61
  else if (x > 400) && (x < 601) { // 401-600
62
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
63
    lcd.clear();
64
    lcd.print ("Bestaetigung    ");
65
  }
66
67
  else if (x > 600) && (x < 801) { // 601-800
68
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
69
    lcd.clear();
70
    lcd.print ("Welcome         ");
71
  }
72
73
  else if (x > 800) && (x < 1023) { // 801-1022
74
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
75
    lcd.clear();
76
    lcd.print ("801-1022        ");
77
  }
78
  delay(250);
79
}
80
81
// bei x gleich 1023 überspringt er die 'if..else if' Abfragen

von Hubert (Gast)


Lesenswert?

Mandi schrieb:
> else if (x > 60) && (x < 201) {  // 61-200

Fehlen da nicht die äußeren Klammern? Ansonsten sieht es passend aus.

von SloJo (Gast)


Lesenswert?

Hubert schrieb:
> Richtig, es muss wie folgt heißen: else if ((x<400) && (x>=200)) {
>
> Jedoch musst du mir noch erklären, warum es deiner Meinung nach nicht
> gebraucht wird.

Ich muss zwar nicht, aber ich tue es trotzdem: Er kommt sowieso nicht in 
den else-Zweig, wenn x < 200 ist. Also brauchst du es da nicht mehr 
abpruefen.

von Mandi (Gast)


Lesenswert?

@Hubert: Klammern vergessen
Korrektur mit Klammern:
1
// mit Arduino-Monitor Ausgabe
2
// include the library code:
3
#include <LiquidCrystal.h>
4
5
// initialize the library with the numbers of the interface pins
6
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
7
8
int i = 0;
9
10
char* myStrings[]={
11
 "GinTonic        ",
12
 "JackyCola       ",
13
 "WodkaBull       ",
14
 "WodkaLemon      ",
15
 "CaptainCola     ",
16
 "Wasser          "};
17
18
void setup() {
19
  Serial.begin(9600);
20
  for (i = 0; i < 6; i++){
21
    Serial.println(myStrings[i]);  // für Testzwecke
22
    delay(1);
23
  }
24
25
    // set up the LCD's number of columns and rows:
26
  lcd.begin(16, 2);
27
    // Print a message to the LCD.
28
  lcd.setCursor(0,0);
29
  lcd.print("Cocktailwahl:   ");
30
  }
31
32
void loop() {
33
34
  int x=0;                         // evtl. x=1023
35
  x = analogRead (0);
36
37
  if ((x > 0) && (x < 61)) {         //  1-60
38
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
39
    lcd.clear();
40
    lcd.print ("Abbruch         ");
41
  }
42
43
  else if ((x > 60) && (x < 201)) {  // 61-200
44
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
45
    lcd.clear();
46
    lcd.print ("GIN             ");
47
  }
48
49
  else if ((x > 200) && (x < 401)) { // 201-400
50
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
51
    lcd.clear();
52
    lcd.setCursor(0,0);
53
    lcd.print(myStrings[i]);
54
    i++;
55
    lcd.setCursor(0,1);
56
    lcd.print(myStrings[i]);
57
    i++;
58
    if (i==6) i=0;                 // Index 0 für GinTonic
59
   }
60
61
  else if ((x > 400) && (x < 601)) { // 401-600
62
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
63
    lcd.clear();
64
    lcd.print ("Bestaetigung    ");
65
  }
66
67
  else if ((x > 600) && (x < 801)) { // 601-800
68
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
69
    lcd.clear();
70
    lcd.print ("Welcome         ");
71
  }
72
73
  else if ((x > 800) && (x < 1023)) { // 801-1022
74
    Serial.print("AnalogRead: ");Serial.println(x);  // für Testzwecke
75
    lcd.clear();
76
    lcd.print ("801-1022        ");
77
  }
78
  delay(250);
79
}
80
81
// bei x gleich 1023 oder 0 überspringt er die 'if..else if' Abfragen

von Katrina N. (Gast)


Lesenswert?

Hey ja super vielen dank, probiere ich gleich mal aus :) Ihr seid echt 
klasse

von Katrina N. (Gast)


Angehängte Dateien:

Lesenswert?

Leider immer noch kein Erfolg......

von Karl (Gast)


Lesenswert?

Mandi schrieb:
> delay(250);

Der Ansatz das Ganze mit delay zu lösen ist doch mist. So wie es jetzt 
ist, wird 4 mal pro Sekunde weitergeschaltet, dass ist für die meisten 
zu schnell. Und was Passiert eigentlich, wenn der Aufruf zu einem 
Zeitpunkt einer steigenden/fallenden Flanke erfolgt? dann wird aufeinmal 
Abbruch gemacht, obwohl Button Down gedrückt wurde!

Mach eine ordentliche Routine, wo die Tastenabfrage gemacht wird. Diese 
wird in einem festen Zyklus ausgeführt (ca. 50 bis 100 ms). In der 
Routine wird der ADC eingelesen und aus dem Ergebnis eine Zuordnung zu 
Button gemacht und mit dem Wert aus dem vorherigen Zyklus verglichen. 
Wenn die gleich sind, wird das Ergebnis weiterverarbeitet. Den Zyklus 
erzeugst du am besten mit einem Timer (keine Angst, da gibt es eine Lib 
für). Im Interrupt setzt du ein Flag. Das Flag wird in der Loop dann 
einfach über eine if-Abfrage abgefragt, und wenn es gesetzt wurde wird 
die Einleseroutine ausgeführt und anschließend das Flag zurückgesetzt.

von Karl (Gast)


Lesenswert?

Katrina N. schrieb:
> Leider immer noch kein Erfolg......

Trenn erstmal deine Aufgaben. Kümmer dich erstmal darum, dass das 
einlesen der Taster funktioniert. Mach das in einer eigenen Funktion.
Dann mach eine Funktion die auf die Taster reagiert.
Teste das alles mit Ausgabe der wichtigsten Variablen über 
Serial.println.
Zum Schluss baust du deinen LCD Text mit ein und fertig.

von Katrina N. (Gast)


Lesenswert?

Karl schrieb:
> Trenn erstmal deine Aufgaben. Kümmer dich erstmal darum, dass das
> einlesen der Taster funktioniert. Mach das in einer eigenen Funktion.
> Dann mach eine Funktion die auf die Taster reagiert.
> Teste das alles mit Ausgabe der wichtigsten Variablen über
> Serial.println.
> Zum Schluss baust du deinen LCD Text mit ein und fertig.

Vielen Dank Karl.

Meine Taster funktionieren ja nur nicht die Ausgabe wenn ich den Taster 
zwei mal drücke, das sich dann der Text ändert.

von djuri (Gast)


Lesenswert?

Hey Katrina
Eine kleine Start Hilfe.
LG.

//
//  Beitrag "Display Arduino"
//
// ====================================================
// Test mit:
// Arduino uno R3
// LCD Keypad Shield 'ROBOT' [ lcd(8, 9, 4, 5, 6, 7); ]
// ====================================================
//
// Die Werte von meinem, [LCD Keypad Shield -ROBOT-] sind:
// --------------------------------------------------------------------
// Dazu R_Netz-       RIGHT,     UP,   DOWN,  LEFT, SELECT, NONE
// werk  neu:   ?!==> R1=3k, R2=330, R3=620, R4=1k,  R5=3k,
// Gerechnet:   U_AD0  =  0,  0.496,  1.203,  1.97,  3.113, (4.995)Volt
// --------------------------------------------------------------------
// Gemessene:             0,     98,    254,   406,    640, 
(1023)[10bit]
// +20  dazu:  ADC     = 20,    118,    274,   426,    660,  1022
// +50  dazu:  ADC     = 50,    148,    304,   456,    690,  1022
// ====================================================================
//
// include the library code:
#include <LiquidCrystal.h>

int test = 1;        //   = 0; // keine 'Serial Monitor' Ausgabe

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int i = 0;             // === Global ===

char* myStrings[]={    // So uebersichtlich
 "GinTonic        ",
 "JackyCola       ",
 "WodkaBull       ",
 "WodkaLemon      ",
 "CaptainCola     ",
 "Wasser          "};  // nach ; // nur noch Kommentar

//----------------------
void setup() {
  Serial.begin(9600);
//=== Serial Monitor === ----------------------------------------
if (test) { Serial.println();      //
  for (int i = 0; i < 6; i++){     // i = === Lokal ===
    Serial.println(myStrings[i]);  // Serial Monitor -> 9600 baud
  } // ende test
//    delay(1);                    // nicht notwendig
    }
//---------------------------------------------------------------
// set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
//  lcd.clear();                    // nicht notwendig
// Print a message to the LCD.
  lcd.setCursor(0,0);
  lcd.print(" W e l c o m e  ");
//lcd.print("1234567890123456");    // nur zur Orientierung

//  delay(1000);                    // nicht notwendig
} // ende setup()
//---------------------------------------------------------------
//
//===============================================================
void loop() {
  int x=0;                          // x = 0 bis 1022
  x = analogRead (0);

// [RIGHT]   ADC wert = 0
  if ((x >= 0) && (x < 50)) {       // x >= 0
if (test) { // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
    Serial.print("AnalogRead: |RIGHT| = ");
    Serial.println(x);
}
    lcd.setCursor(0,1);
    lcd.print ("RIGHT  =        ");
  //lcd.print ("1234567890123456");
    lcd.setCursor(9,1);
    lcd.print (x);
  } // ende |RIGHT|

// [UP]   ADC wert = 98
  else if ((x >= 50) && (x < 148)) {
    Serial.print("AnalogRead: |UP|    = ");
    Serial.println(x);
    lcd.setCursor(0,1);
    lcd.print ("UP     =        ");
  //lcd.print ("1234567890123456");
    lcd.setCursor(9,1);
    lcd.print (x);
  } // ende |UP|

// =========================================================
// Menue Angebot (myStrings
// ========================
// [DOWN]   ADC wert = 254
  else if ((x >= 148) && (x < 304)) {
    Serial.print("AnalogRead: |DOWN|  = ");
    Serial.println(x);
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;                                // Global
   } // ende |DOWN|
// =========================================================

// [LEFT]   ADC wert = 406
  else if ((x >= 304) && (x < 456)) {
    Serial.print("AnalogRead: |LEFT|  = ");
    Serial.println(x);
    lcd.setCursor(0,1);
    lcd.print ("LEFT   =        ");
  //lcd.print ("1234567890123456");
    lcd.setCursor(9,1);
    lcd.print (x);
  } // ende |LEFT|

// [SELECT]   ADC wert = 640
  else if ((x >= 456) && (x < 690)) {
    Serial.print("AnalogRead: |SELECT|= ");
    Serial.println(x);
    lcd.setCursor(0,1);
    lcd.print ("SELECT =        ");
  //lcd.print ("1234567890123456");
    lcd.setCursor(9,1);
    lcd.print (x);
  } // ende |SELECT|

// [NONE]   ADC wert = 1022
  else if ((x >= 690) && (x <= 1023)) {
    Serial.print("AnalogRead: |NONE|   = ");
    Serial.println(x);
    lcd.setCursor(0,1);              // es wird ueberschrieben
    lcd.print ("NONE   =        ");  // =
  //lcd.print ("1234567890123456");  // =
    lcd.setCursor(9,1);              // =
    lcd.print (x);                   // =

    lcd.setCursor(0,1);              // und weiter gets,
    lcd.print ("  Cocktailwahl  ");  // =
  //lcd.print ("1234567890123456");
  } // ende |NONE|

  if (i==6) i=0;        // Beim Cocktailwahl BLEIBEN!
// ==============       // sonst ist er in nirwana
// ===================================================
  delay(250);           // ersaetzen, ???
} // ende loop()

// =========================================================
// Die 'if' schleifen {Innereien} in Funktionen verbahnen,
// oder mit 'switch' und Funktion den 'delay()' loswerden.
// Cocktail Auswahl aufbauen,
// Auswaehlen, bestaetigen, zahlen,
// danken und weiter mit Welkome.
// =========================================================
// Achte auf die Gueltigkeit der Variablen.
// Zuruecksetzen nicht vergessen.
// ==============================================================
//

von Mark B. (markbrandis)


Lesenswert?

djuri schrieb:
> // Die 'if' schleifen

So etwas gibt es nicht.

Was es gibt, sind bedingte Verzweigungen.

von Dieter F. (Gast)


Lesenswert?

Da würde ich mich eher daran

http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)

halten und dort meine Logik einbauen.

Bei den Tasten, wo nichts passieren soll, belässt Du es in der 
CASE-Anweisung einfach bei einem BREAK.

Ich würde auch nicht jedesmal ein lcd.clear() hinpacken, das macht die 
Display-Ausgabe nur "unruhig". Einfach überschreiben (mit ausreichend 
Leerzeichen am Ende) tut es auch und verhindert das "Flackern".

von Mick (Gast)


Lesenswert?

Schau dir das hier mal an: https://code.google.com/p/u8glib/wiki/tmenu

Abfragen der Taster könnte wie folgt aussehen. Dabei wird jeweils nur 
ein "Click" erkannt. Bevor eine weitere Taste erkannt wird, muss der 
gedrückte Schalter zuerst losgelassen werden. Die entsprechenden 
Analogwerde musst du halt noch anpassen.
1
/*-----( Declare Constants )-----*/
2
#define btnRIGHT  0
3
#define btnUP     1
4
#define btnDOWN   2
5
#define btnLEFT   3
6
#define btnSELECT 4
7
#define btnNONE   5
8
9
/*-----( Declare Variables )-----*/
10
int adc_key_prev  = 0;
11
int adc_key_current  = 0;
12
13
void loop(){
14
  adc_key_in = read_LCD_buttons();
15
  if(adc_key_prev != adc_key_current){
16
    /*
17
    dein code hier
18
    */
19
    adc_key_prev = adc_key_current;
20
  }
21
}
22
23
int read_LCD_buttons(){
24
  int adc_key_in = analogRead(0);      // read the value from the sensor 
25
  delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned.
26
  int k = (analogRead(0) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise
27
  if (5 < abs(k)) return btnNONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again.
28
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
29
  // we add approx 50 to those values and check to see if we are close
30
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
31
  if (adc_key_in < 50)   return btnRIGHT;  
32
  if (adc_key_in < 195)  return btnUP; 
33
  if (adc_key_in < 380)  return btnDOWN; 
34
  if (adc_key_in < 555)  return btnLEFT; 
35
  if (adc_key_in < 790)  return btnSELECT;   
36
  return btnNONE;  // when all others fail, return this...
37
}

von Katrina N. (Gast)


Lesenswert?

Hey danke an euch alle bin jetzt schon einen rießen Großen Schritt 
weitergekommen das mit Down geht bis auf das letzte up hängt sich noch 
auf. hier mein Aktuelles Skript:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char* buttons[]={"Abbruch         ","Bestaetigung    ","Welcome 
"};
char* myStrings[]={    // So uebersichtlich
 "GinTonic        ",
 "JackyCola       ",
 "WodkaBull       ",
 "WodkaLemon      ",
 "CaptainCola     ",
 "Wasser          "};
int i=0;
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0,0);
  lcd.print("    WELCOME     ");
  lcd.setCursor(0,1);
  lcd.print("  Cocktailwahl  ");

}

void loop() {
  int x;

  x = analogRead (0);
  lcd.setCursor(0,0);
  if ((x >= 0) && (x < 50)) {
     lcd.setCursor(0,1);
    lcd.print (buttons[0]);
  }
  else if ((x >= 50) && (x < 148)) {
  lcd.print ("UP              ");
//    lcd.setCursor(0,0);
//    lcd.print(myStrings[i]);
//    i--;
//    lcd.setCursor(0,1);
//    lcd.print(myStrings[i]);
//    i--;
  }
  else if ((x >= 304) && (x < 456)) {
    lcd.setCursor(0,0);
    lcd.print(myStrings[i]);
    i++;
    lcd.setCursor(0,1);
    lcd.print(myStrings[i]);
    i++;

   }

 else if ((x >= 456) && (x < 690)) {
   lcd.setCursor(0,1);
    lcd.print (buttons[1]);
  }
  else if ((x >= 148) && (x < 304)) {
  lcd.setCursor(0,1);
    lcd.print (buttons[2]);
  }
   if (i==6)
   {    i=0;
        lcd.setCursor(0,0);              // und weiter gets,
        lcd.print ("  Cocktailwahl  ");
   }
}

von Dieter F. (Gast)


Lesenswert?

Katrina N. schrieb:
> hier mein Aktuelles Skript

O.K., dann bin ich hier raus.

Ich verstehe nicht, warum Du das recht gut strukturierte Beispiel aus

http://www.dfrobot.com/wiki/index.php/LCD_KeyPad_Shield_For_Arduino_SKU:_DFR0009

nicht nutzt - aber Du wirst schon Deine Gründe haben.

von Katrina N. (Gast)


Lesenswert?

Ich war jetzt einfach nur froh, dass es geklappt hat @Dieter F.
Eine Frage wie kann ich es verhindern, das er bei längerem Drücken 
trotzdem weiterzählt? Wollen die Taster jetzt über Digitale Eingänge 
schalten, ist es dann weg?

von Dieter F. (Gast)


Lesenswert?

Katrina N. schrieb:
> Eine Frage wie kann ich es verhindern, das er bei längerem Drücken
> trotzdem weiterzählt?

In diesem Fall würde ich ganz einfach nach jeder vollständigen Ausgabe 
ein Delay mit 500 - 1000 ms setzen, also z.B.
1
...
2
    lcd.setCursor(0,0);
3
    lcd.print(myStrings[i]);
4
    i++;
5
    lcd.setCursor(0,1);
6
    lcd.print(myStrings[i]);
7
    i++;    
8
    delay(500);
9
...

Dann hat derjenige, der auf die Taste drückt, nach der vollständigen 
Ausgabe des neuen Display-Inhaltes (er sieht das Ergebnis des 
Tastendrucks) noch 500 ms Zeit, den Finger von der Taste zu nehmen. Die 
erforderliche Zeit musst Du halt ausprobieren.

von Katrina N. (Gast)


Lesenswert?

Stimmt auf die einfache Idee bin ich gar nicht gekommen :D

von Mandi (Gast)


Lesenswert?

für die UP-Taste:
1
...
2
  else if ((x >= 50) && (x < 148)) {
3
  lcd.print ("UP              ");
4
    lcd.setCursor(0,1);
5
    lcd.print(myStrings[i]);
6
    i--;
7
    lcd.setCursor(0,0);
8
    lcd.print(myStrings[i]);
9
    i--;
10
    if (i==0) i=6;     // nach Menüpunkt 1 wieder Menüpunkt 6
11
  }
12
...

von Mandi (Gast)


Lesenswert?

Ganzes Beispiel:
(nicht getestet, keine Arduino-IDE auf Internet-PC)
1
// include the library code:
2
#include <LiquidCrystal.h>
3
4
// initialize the library with the numbers of the interface pins
5
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
6
7
char* buttons[]={
8
 "Abbruch         ",
9
 "Bestaetigung    ",
10
 "Welcome         "};
11
12
char* myStrings[]={    // So uebersichtlich
13
 "GinTonic        ",
14
 "JackyCola       ",
15
 "WodkaBull       ",
16
 "WodkaLemon      ",
17
 "CaptainCola     ",
18
 "Wasser          "};
19
20
int i=0;
21
22
void setup() {
23
    // set up the LCD's number of columns and rows:
24
  lcd.begin(16, 2);
25
    // Print a message to the LCD.
26
  lcd.setCursor(0,0);
27
  lcd.print("    WELCOME     ");
28
  lcd.setCursor(0,1);
29
  lcd.print("  Cocktailwahl  ");
30
}
31
32
void loop() {
33
  int x;
34
  x = analogRead (0);
35
36
  if ((x >= 0) && (x < 50)) {          // Abbruch
37
    lcd.setCursor(0,1);
38
    lcd.print (buttons[0]);
39
    delay(500);   // Wartezeit für nächsten Tastendruck
40
  }
41
  else if ((x >= 50) && (x < 148)) {   // UP
42
    if (i<1) i=6;
43
    i--;
44
    lcd.setCursor(0,1);
45
    lcd.print(myStrings[i]);
46
    i--;
47
    lcd.setCursor(0,0);
48
    lcd.print(myStrings[i]);
49
    delay(500);   // Wartezeit für nächsten Tastendruck
50
  }
51
  else if ((x >= 304) && (x < 456)) {  // Down
52
    if (i>5) i=0;
53
    lcd.setCursor(0,0);
54
    lcd.print(myStrings[i]);
55
    i++;
56
    lcd.setCursor(0,1);
57
    lcd.print(myStrings[i]);
58
    i++;
59
    delay(500);   // Wartezeit für nächsten Tastendruck
60
  }
61
  else if ((x >= 456) && (x < 690)) {   // Bestaetigung
62
    lcd.setCursor(0,1);
63
    lcd.print (buttons[1]);
64
    delay(500);   // Wartezeit für nächsten Tastendruck
65
  }
66
  else if ((x >= 148) && (x < 304)) {  // Welcome
67
    lcd.setCursor(0,1);
68
    lcd.print (buttons[2]);
69
    delay(500);   // Wartezeit für nächsten Tastendruck
70
  }
71
72
// wird gebraucht?
73
//    {    i=0;
74
//         lcd.setCursor(0,0);            // und weiter gehts,
75
//         lcd.print ("  Cocktailwahl  ");
76
//    }
77
} // Ende Loop

von Mandi (Gast)


Lesenswert?

kleine Korrektur!
(vom letzten Beispiel)
1
// in UP:
2
    if (i<1) i=6;
3
ändern zu
4
    if (i<2) i=6;
5
6
// in Down:
7
    if (i>5) i=0;
8
ändern zu
9
    if (i>4) i=0;

von Eric B. (beric)


Lesenswert?

Mal 2 dumme Fragen:
1. Es stehen im Display immer 2 Getränke zum Auswahl, welche von Beiden 
krieg ich serviert wenn ich auf "Bestätigung" drücke?

2. Was passiert wenn mal eine ungerade Anzahl an Getränken zur Auswahl 
stehen soll (also z.B. 5 oder 7, statt 6)?

von Mandi (Gast)


Lesenswert?

@Eric B.
 Ausgabe nur eines Getränks in Zeile 1, mit Up und Down bedienbar.
Sollte nur als erweiterbares Beispiel für Katrina N. dienen.
1
// include the library code:
2
#include <LiquidCrystal.h>
3
4
// initialize the library with the numbers of the interface pins
5
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
6
7
char* buttons[]={
8
 "Abbruch         ",
9
 "Bestaetigung    ",
10
 "Welcome         "};
11
12
char* myStrings[]={    // So uebersichtlich
13
 "GinTonic        ",
14
 "JackyCola       ",
15
 "WodkaBull       ",
16
 "WodkaLemon      ",
17
 "CaptainCola     ",
18
 "Wasser          "};
19
20
int Max_Anzahl_Cocktail=6;  // Anzahl Cocktails in myStrings[]
21
int Taste=0;
22
int i=0;
23
24
void setup() {
25
    // set up the LCD's number of columns and rows:
26
  lcd.begin(16, 2);
27
    // Print a message to the LCD.
28
  lcd.setCursor(0,0);
29
  lcd.print("    WELCOME     ");
30
  lcd.setCursor(0,1);
31
  lcd.print("  Cocktailwahl  ");
32
}
33
34
void loop() {
35
  int x;
36
  x = analogRead (0);
37
38
  if ((x >= 0) && (x < 50)) {          // Abbruch
39
    lcd.setCursor(0,1);
40
    lcd.print (buttons[0]);
41
    delay(500);   // Wartezeit für nächsten Tastendruck
42
  }
43
  else if ((x >= 50) && (x < 148)) {   // UP
44
    if (Taste==0) i--;
45
    if (i<1) i=Max_Anzahl_Cocktail;
46
    i--;
47
    lcd.setCursor(0,0);
48
    lcd.print(myStrings[i]);
49
    Taste=1;
50
    delay(500);   // Wartezeit für nächsten Tastendruck
51
  }
52
  else if ((x >= 304) && (x < 456)) {  // Down
53
    if (Taste==1) i++;
54
    if (i>Max_Anzahl_Cocktail-1) i=0;
55
    lcd.setCursor(0,0);
56
    lcd.print(myStrings[i]);
57
    i++;
58
    Taste=0;
59
    delay(500);   // Wartezeit für nächsten Tastendruck
60
  }
61
  else if ((x >= 456) && (x < 690)) {   // Bestaetigung
62
    lcd.setCursor(0,1);
63
    lcd.print (buttons[1]);
64
    delay(500);   // Wartezeit für nächsten Tastendruck
65
  }
66
  else if ((x >= 148) && (x < 304)) {  // Welcome
67
    lcd.setCursor(0,1);
68
    lcd.print (buttons[2]);
69
    delay(500);   // Wartezeit für nächsten Tastendruck
70
  }
71
72
// wird gebraucht?
73
//    {    i=0;
74
//         lcd.setCursor(0,0);            // und weiter gehts,
75
//         lcd.print ("  Cocktailwahl  ");
76
//    }
77
} // Ende Loop

von Karl (Gast)


Lesenswert?

Dieter F. schrieb:
> In diesem Fall würde ich ganz einfach nach jeder vollständigen Ausgabe
> ein Delay mit 500 - 1000 ms setzen, also z.B.

Genau, am besten gleich 1000 ms, dann dauert es bei 10 Getränken min 10 
s bis ich habe, was ich will. Schon mal ein PC/Smartphone benutzt, wo 
man nach jeder Aktion 0,5 bis 1 s warten muss, bis etwas passiert? Das 
würde jeder Nutzer als unbrauchbar wegfeuern!

von Dieter F. (Gast)


Lesenswert?

Karl schrieb:
> Genau, am besten gleich 1000 ms, dann dauert es bei 10 Getränken min 10
> s bis ich habe, was ich will. Schon mal ein PC/Smartphone benutzt, wo
> man nach jeder Aktion 0,5 bis 1 s warten muss, bis etwas passiert? Das
> würde jeder Nutzer als unbrauchbar wegfeuern!

Bei 500 ms dauert es 5 Sekunden einmal durchzuscrollen. Außerdem 
solltest Du wenigstens vollständig zitieren:

Dieter F. schrieb:
> Dann hat derjenige, der auf die Taste drückt, nach der vollständigen
> Ausgabe des neuen Display-Inhaltes (er sieht das Ergebnis des
> Tastendrucks) noch 500 ms Zeit, den Finger von der Taste zu nehmen. Die
> erforderliche Zeit musst Du halt ausprobieren.

Aber Du kannst ja gerne eine bessere Lösung vorschlagen :-)

von avr (Gast)


Lesenswert?

Dieter F. schrieb:
> Aber Du kannst ja gerne eine bessere Lösung vorschlagen :-)

Alle Delays raus und dann eine anständige Tastenentprellung rein. Alles 
andere ist Pfusch.

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

avr schrieb:
> Alle Delays raus und dann eine anständige Tastenentprellung rein. Alles
> andere ist Pfusch.

Ah ja, dann zeigt doch mal ein Beispiel der Entprellung für das "LCD 
Keypad Shield", welches die Tastendrücke anhand des Einflusses des 
Widerstandswerts (liegt eine "Dekade" dahinter) auswertet. Ich bin 
gespannt ...

von Eric B. (beric)


Lesenswert?

Dieter F. schrieb:
> Ah ja, dann zeigt doch mal ein Beispiel der Entprellung für das "LCD
> Keypad Shield", welches die Tastendrücke anhand des Einflusses des
> Widerstandswerts (liegt eine "Dekade" dahinter) auswertet. Ich bin
> gespannt ...

In Pseudo code:
1
var tasten_status = NO_KEY
2
    entpreller = 0
3
    adcwert = 0
4
    alter_adcwert = 0
5
6
const ENTPRELL_LIMIT = 8 // Experimentell ermitteln!
7
8
loop:
9
  adcwert = adc lesen
10
  adcstatus = ermittele_tasten_status(adcwert)
11
12
  if adcstatus == alter_adcstatus:
13
    entpreller ++
14
    if entpreller == ENTPRELL_LIMIT:
15
      tastenstatus = adcstatus
16
      entpreller = 0
17
    end if
18
  else
19
    entpreller = 0
20
  end if
21
  alter_adc_status = adc_status
22
23
  tue_was_mit(tasten_status)

: Bearbeitet durch User
von avr (Gast)


Lesenswert?

Dieter F. schrieb:
> Ah ja, dann zeigt doch mal ein Beispiel der Entprellung für das "LCD
> Keypad Shield", welches die Tastendrücke anhand des Einflusses des
> Widerstandswerts (liegt eine "Dekade" dahinter) auswertet. Ich bin
> gespannt ...

Was man entprellt ist doch völlig egal. Man hat hier eine Information, 
die angibt welcher Taster gedrückt ist. Diese Information kann aber 
"prellen". Sobald man eindeutig, den Tastendruck und das Loslassen 
erkennt, kann man mit diesen Event das Menü aufbauen.

Pseusocode habt ihr ja schon wieder bekommen. Ich finde bei solchen 
Sachen wie Entprellung, zu dem es auch sehr viel im Internet schon zu 
lesen gibt, hätte man sich auch selbst mal Gedanken machen können.

von djuri (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, Katrina
Die Lösung ist nicht ganz, in deinem sine, hoffe aber das Dir weiter 
hilft.
Es geht wunderbar, auch OHNE:  delay()   und   Tastenentprellung!
Finde heraus:  Welcher  Taster?  Für was gut ist?

Gruß.

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.