Tochscreen-Display mit Menue-Steuerung

Hallo mal wieder
Ich arbeite gerade an ein Projekt, welches ein Menü aus mehreren Seiten auf einem Touchscreen-Display darstellen und steuern soll. Es sollen später auf einer Seite Einstellungen (z.B. Uhrzeit) vorgenommen werden und auf einer anderen Seite einige Daten angezeigt werden.

Ich habe soweit als erstes eine Startseite erstellt, die durch einen einfachen Touch auf das Display zur nächsten Seite "Menue" (menue) springt. Dort habe ich zwei Button erstellt, die im Moment des Betätigens einen roten Rand haben, damit die Betätigung auch visuell erkennbar ist. Beim Betätigen des oberen Button, springt die Anzeige auf die Seite "Einstellungen" (setting). Beim Betätigen des unteren Button, springt die Anzeige auf die Seite "Startseite". Auf der Seite "Einstellungen" gibt es nur einen Button, der beim Betätigen die Seite "Menue" springt.

Nun zum Problem: Ich drücke auf der Startseite auf das Display>das Display springt auf die Menue-Seite. Danach drücke ich auf dieser Seite den unteren Button > das Display springt auf die Einstellungen-Seite. Drücke ich auf dieser Seite den einzelnen Button>springt das Display wieder auf die Startseite. Dort ins Display gedrückt>springt das Display wieder auf die Menue-Seite.
Bis jetzt ist alles so wie es sein soll. Nur geht es hier nicht mehr weiter. Ich kann nur noch den oberen Button betätigen(wird auch rot umrandet), aber leider springt das Display immer wieder in sich selbst(Menue-Seite) und der andere Button hat keine Funktion mehr.
Das selbe habe ich auch wenn ich von der Startseite>Menue-Seite>oberer Button drücken>Einstellungen-Seite>einziger Button drücken(soll eigentlich auf die Menue-Seite springen), springt das Display immer wieder in sich selbst(Einstellungen-Seite).

Anbei unten der Sketch und ein paar Bilder von den Screens.

Ich vermute einmal, dass im loop irgendetwas faul ist oder etwas fehlt und ich komme nicht drauf.

Hat vielleicht jemand eine Idee?

Vielen Dank schon mal.

// Remember to change the next line if you are using as 16bit module!
#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <avr/pgmspace.h>

// Schriftarten in Benutzung
extern uint8_t SmallFont[];
extern uint8_t Sinclair_S[];
extern uint8_t Sinclair_M[];
extern uint8_t BigFont[];


//Pinbelegung für das Display+Touchscreen
//myGLCD(RS,WR,CS,RST,ALE,mode);
ITDB02 myGLCD(A1,A2,A0,A3,A5,ITDB32S);
//myTouch(TCLK,TCS,DIN,DOUT,IRQ);
ITDB02_Touch  myTouch(13,10,11,12,A4);


//Konstanten
int cx, cy;
int rx[10], ry[10];
float px, py;
int ox, oy;
int x, y;
char stCurrent[20]="";
int stCurrentLen=0;
char stLast[20]="";


void setup()
{
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(Sinclair_S);

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_LOW);
}

/*void waitForTouchRelease()
{
  // Wait for release
  while (myTouch.dataAvailable()==true)
    myTouch.read();
}*/

void waitForTouch()
{
  while (myTouch.dataAvailable() == true)
  {
    myTouch.read();
  }
  while (myTouch.dataAvailable() == false) {}
  while (myTouch.dataAvailable() == true)
  {
    myTouch.read();
  }}
  
  
//zeichnet eine rote Umrandung, wenn der Button gedrückt wird
void waitForIt(int x1, int y1, int x2, int y2)
{
  myGLCD.setColor(255, 0, 0);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
  while (myTouch.dataAvailable())
    myTouch.read();
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
}

//Aufbau der Startseite
void startseite()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 0, 0, 237);
 myGLCD.fillRect(0, 0, 239, 12);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Startseite by Knippi", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);
   myGLCD.setFont(Sinclair_M);
  myGLCD.print("Startseite", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
    myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
  waitForTouch();
   
}

//Aufbau der Menueseite
void menue()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  //myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(255, 255, 0);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 255, 255, 0);     //setzt die Farbe des Farbbalkens oben
 myGLCD.fillRect(0, 0, 239, 13);  //setzt die Größe und Position des Hintergrundes des Balkens oben
  myGLCD.setColor(0, 0, 0);       //setzt die Schriftfarbe für den nachfolgenden Text
  myGLCD.print("Menue", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);   //setzt die Schriftfarbe für den nachfolgenden Texte
   myGLCD.setFont(Sinclair_M);
    myGLCD.setColor(255, 255, 255);
  myGLCD.print("Menue", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
   /* myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);*/
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
   //waitForTouch();
      myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (10, 60, 60, 10);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (10, 60, 60, 10);
     myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (60, 130, 10, 80);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (60, 130, 10, 80);
    //myGLCD.print("1", 28, 27);
// waitForTouch();   
  waitForIt(10, 10, 60, 60);
}

//Aufbau der Settingseite
void setting()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(255, 0, 0);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 255, 0, 0);     //setzt die Farbe des Farbbalkens oben
 myGLCD.fillRect(0, 0, 239, 12);  //setzt die Größe und Position des Hintergrundes des Balkens oben
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Einstellungen", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);
   myGLCD.setFont(Sinclair_M);
  myGLCD.print("Einstellungen", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
  /*  myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);*/
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
   //waitForTouch();
     myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (10, 60, 60, 10);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (10, 60, 60, 10);
    //myGLCD.print("1", 28, 27);
// waitForTouch();  
  waitForIt(10, 10, 60, 60);

}

void loop ()
{
  startseite();
  menue();
   // Betätigunsfunktion des oberer Button auf der Menueseite
    while (true)
  {
    if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if ((y>=10) && (y<=60))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 10, 60, 60); //Größe des roten Umrandung
          setting();
      }
      //Betätigunsfunktion des unteren Button auf der Menueseite
      else if((y>=80) && (y<=130))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 80, 60, 130); //Größe des roten Umrandung
    
startseite();
        
  
  setting();
  //Betätigunsfunktion des Button auf der Settingseite
  {
    if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if ((y>=10) && (y<=60))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 10, 60, 60); //Größe des roten Umrandung
          menue();
   delay(10);       
}}}}}}}

Irgendwie fehlte da noch das eine Bild.
Anbei

Gruß Jens

Du solltest Deinen Code anders struktuieren. Verwende eine "mode"-Variable, die den aktuellen Status bzw. Modus repräsentiert. Dann ist mode==0 Deine Startseite, mode==1 entspricht Deiner Menuseite usw. Beim Drücken der Buttons wird dann einfach der mode hochgezählt:

#define MODE_COUNT 3

if (buttonpress) {
  mode = (mode + 1) % MODE_COUNT;
}

Zur Anzeige kannst Du dann einfach ein if-else-Konstrukt nehmen:

if (mode == 0) {
  startseite();
} else if (mode == 1) {
  menue();
} else if (mode == 2) {
  setting();
} else {
  show_error();
}

Ein switch-Statement wäre auch möglich, aber das verwende ich aus Speichergründen erst ab sehr vielen möglichen Zuständen.

Mit einer solchen "State Machine" sind die Fehler, wie Du sie schilderst viel unwahrscheinlicher, weil sie schnell offensichtlich werden. Du musst so nämlich nur noch die Voraussetzungen für einen Status-Wechsel programmieren, die "mode"-Variable entsprechend setzen und nicht in einer unübersichtlich verschachtelten if-else-Konstruktion jede mögliche Kombination abhandeln.

Hallo pylon,
vielen Dank für deine Unterstützung. Ich hatte schon die Hoffnung aufgegeben, das mir jemand mal unter die Arme greift.
Ich bin blutiger Anfänger, deshalb stellen sich für mich noch ab und an einige Fragen.
Vielleicht kann mir der ein oder andere aus dem Forum diese erklären.
Wofür ist dieser Befehl?

#define MODE_COUNT 3

Ich erkläre mir das so, dass dieser einen Counter(Zähler) definiert. Wozu steht der Begriff MODE und der Begriff COUNT und wofür steht die Zahl 3?
Ich gehe einmal davon aus, dass dieser Befehl wie folgt in meinem Sketch an dieser Stelle eingebunden wird, wie auch die Steuerbefehle des Display und des Touchscreen eingebunden sind richtig?

// Remember to change the next line if you are using as 16bit module!
#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <avr/pgmspace.h>
#define MODE_COUNT 3

Gehe ich richtig in der Annahme, dass ich "buttonpress" gegen die Touchfunktion eines Buttons ersetzen muss und gehört dieser Teil in den loop Bereich? Was passiert hier in diesem Teil?

if (buttonpress) {
  mode = (mode + 1) % MODE_COUNT;
}

Also so: und das für jeden Button einzeln?

if (if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if ((y>=10) && (y<=60))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 10, 60, 60); //Größe des roten Umrandung
      }}) {
  mode = (mode + 1) % MODE_COUNT;
}

Oder wäre das eleganter? für jeden Button und dann durchnummeriert?

void buttonpress1()
{
if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if ((y>=10) && (y<=60))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 10, 60, 60); //Größe des roten Umrandung
      }}}
void buttonpress2()
{
if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
     if ((y>=80) && (y<=130))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239)))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 10, 60, 60); //Größe des roten Umrandung
      }}}

Als letztes dann noch dieser Teil:

if (mode == 0) {
  startseite();
} else if (mode == 1) {
  menue();
} else if (mode == 2) {
  setting();
} else {
  show_error();
}

Wie du schon erklärt hast werden in diesem Teil , die einzelnen Seiten (startseite;menue;setting) den mode (z.B mode==0 ist die Startseite) zugeordnet und angezeigt. Aber woher kommt denn jetzt die Zuordnung eines Button zu den mode==0?

Ich hoffe, ich verschrecke mit den vielen und wahrscheinlich dilettantischen Fragen niemanden und verbaue mir so eine Antwort auf mein Problem. Ich möchte noch sehr viel zu dem Arduino lernen. Als Anfänger ist das ein oder andere aber immer noch wie bömische Dörfer. :fearful:
Es wäre auch schon gut, wenn der ein oder andere nur einen Teil beantworten würde und dann letztendlich ein ganzes Beantwortung dabei heraus käme. :slight_smile:
Vielen Dank, schon mal.
Gruß Jens

Wofür ist dieser Befehl?

Zuerst die lange Erkärung: dies ist eine Precompiler-Anweisung, die eine Ersetzung (auch Macro) definiert. Sie sagt aus, dass der Precompiler (der analysiert den Source-Code for der Kompilation und erledigt solche Sachen wie das Inkludieren von anderen Dateien oder das Auflösen von Macros) jedes weitere Auftreten der Zeichenfolge "MODE_COUNT" ersetzen soll durch "3".
Kurz: Ich definiere so etwas wie eine Konstante. Damit kann ich im Code dann immer diese Zeichenfolge verwenden und muss später nicht überall das Auftreten der 3 suchen gehen, wenn ich es auf 4 wechseln will.
MODE kommt von Modus (das englische Wort dafür), COUNT von zählen. Es ist also die Anzahl der Modi, die ich gesamthaft habe. Ich verwende im Source-Code prinzipiell nur englische Begriffe, weil diese keine Umlaute enthalten (Encoding-Problem vermieden) und weil ich so nichts umschreiben muss, wenn ich etwas weitergeben will.

Ich gehe einmal davon aus, dass dieser Befehl wie folgt in meinem Sketch an dieser Stelle eingebunden wird, wie auch die Steuerbefehle des Display und des Touchscreen eingebunden sind richtig?

Korrekt.

Gehe ich richtig in der Annahme, dass ich "buttonpress" gegen die Touchfunktion eines Buttons ersetzen muss und gehört dieser Teil in den loop Bereich? Was passiert hier in diesem Teil?

Ja, das ist richtig. Hier wird die "mode"-Variable eins hochgezählt und gleichzeitig bei einer Überschreitung der MODE_COUNT-Grenze wieder auf 0 zurückgesetzt. Dies geschieht mittel der sog. Modulo-Anweisung. Dabei wird der erste Operand ganzzahlig durch den zweiten geteilt, aber das Resultat ist nicht das Ergebnis der Division, sondern der Rest, der nicht ganzzahlig geteilt werden kann:

5 % 2 = 1
14 % 4 = 2
15 % 5 = 0

Also so: und das für jeden Button einzeln?

Nein, nur für den Button, der eins weiterschaltet. Für den Rückwärtsbutton würde das dann so aussehen:

mode = (mode + MODE_COUNT - 1) % MODE_COUNT;

Oder wäre das eleganter? für jeden Button und dann durchnummeriert?

Nein, genau damit solltest Du ja aufhören. Zu solch durchnummerierten Funktionen greift man nur, wenn nichts anderes mehr geht, was in der Realität praktisch nie vorkommt. Meist lässt sich sowas über Arrays oder eben eine State Machine (was wir hier versuchen) vermeiden.

Aber woher kommt denn jetzt die Zuordnung eines Button zu den mode==0?

Gar nicht. Das solltest Du ja nicht mehr brauchen. Es kann natürlich sein, dass ich etwas falsch interpretiert habe, aber wenn Du einen Button hast, der auf jeder Seite auf die nächste schaltet, dann brauchst Du den ja nur einmal.

Hallo pylon,
danke für die Erklärungen. So langsam verstehe ich das Prinzip. Ich habe den loop mal für die "startseite" eingefügt. Hier sollte einfach nur irgendwo in das Display gedrückt werden und dann auf die Seite "menue" wechseln.
Ich bekomme dann die im Bild nachfolgende Fehlermeldung. Muss für mode nicht noch irgendetwas definiert oder gesetzt werden?
Genau das war glaube ich das, was noch gefehlt hat. Auf jedenfall kommt keine Fehlermeldung(Bild "touch1") mehr.
Habe noch folgendes eingefügt:

int mode();

Was macht dieser Eintrag eigentlich?

Nun habe ich überlegt, was in diesem Teil passiert.

]if (myTouch.dataAvailable()) {

mode = (mode + 1) % MODE_COUNT;
}

Hier wird doch der touch auf dem Bildschirm registriert und nachfolgend der mode berechnet. Richtig?

if (myTouch.dataAvailable())

Das Ergebnis von dem mode, müsste dann so aussehen:

mode = (mode + 1) % MODE_COUNT;
mode= (0+1)/3
mode=0

also springt es wieder auf die "startseite" zurück. Aber es soll auf die Seite "menue" springen.

Nun habe ich mal den Wert auf 4 erhöht und das Ergebnis wäre doch 1 oder?

mode = (mode + 4) % MODE_COUNT;
mode= (0+3)/3
mode=1

Ja, das ist richtig. Hier wird die "mode"-Variable eins hochgezählt und gleichzeitig bei einer Überschreitung der MODE_COUNT-Grenze wieder auf 0 zurückgesetzt. Dies geschieht mittel der sog. Modulo-Anweisung. Dabei wird der erste Operand ganzzahlig durch den zweiten geteilt, aber das Resultat ist nicht das Ergebnis der Division, sondern der Rest, der nicht ganzzahlig geteilt werden kann:

5 % 2 = 1
14 % 4 = 2
15 % 5 = 0
4 % 3 = 1

und damit müsste es doch auf die Seite "menue" springen, was es aber nicht macht.

else if (mode == 1) {
  menue();
}

Gruß Jens

Was macht dieser Eintrag eigentlich?

Das müsste

int mode = 0;

heissen. Dein Code würde eine Funktion mode() definieren, die Du später auch auschreiben müsstest.

Hier wird doch der touch auf dem Bildschirm registriert und nachfolgend der mode berechnet. Richtig?

Ja, das stimmt in etwa. Allerdings prüft myTouch.dataAvailable() meines Wissens nur, ob ein Touch stattgefunden hat. Somit würde der Modus bei jedem Touch gewechselt, wenn Du den Code so übernimmst.

mode = (mode + 1) % MODE_COUNT;
mode= (0+1)/3
mode=0

Das ist falsch. Richtig wäre:

mode = (0 + 1) % 3
mode = 1

Das Prozentzeichen ist keine Division, sondern die Modulo-Operation, als der Rest einer ganzzahligen Division. 1 modulo 3 ist 1 und nicht 0.

Post mal den ganzen Code, mit dem Du momentan herumexperimentierst, dann finden wir vielleicht das Problem.

Hallo pylon,

ich habe

int mode (); gegen
int mode = 0; ersetzt.

Leider keine Änderung. Beim touch auf die "startseite" springt das Display wieder auf die "startseite" und nicht auf die "menue"-Seite.
Anbei mal den kompletten Sketch mit dem ich experimentiere.

// Remember to change the next line if you are using as 16bit module!
#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <avr/pgmspace.h>
#define MODE_COUNT 3

// Schriftarten in Benutzung
extern uint8_t SmallFont[];
extern uint8_t Sinclair_S[];
extern uint8_t Sinclair_M[];
extern uint8_t BigFont[];


//Pinbelegung für das Display+Touchscreen
//myGLCD(RS,WR,CS,RST,ALE,mode);
ITDB02 myGLCD(A1,A2,A0,A3,A5,ITDB32S);
//myTouch(TCLK,TCS,DIN,DOUT,IRQ);
ITDB02_Touch  myTouch(13,10,11,12,A4);


//Konstanten
int cx, cy;
int rx[10], ry[10];
float px, py;
int ox, oy;
int x, y;
char stCurrent[20]="";
int stCurrentLen=0;
char stLast[20]="";
int mode = 0;


void setup()
{
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(Sinclair_S);

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_LOW);
}

/*void waitForTouchRelease()
{
  // Wait for release
  while (myTouch.dataAvailable()==true)
    myTouch.read();
}*/

void waitForTouch()
{
  while (myTouch.dataAvailable() == true)
  {
    myTouch.read();
  }
  while (myTouch.dataAvailable() == false) {}
  while (myTouch.dataAvailable() == true)
  {
    myTouch.read();
  }}
  
  
//zeichnet eine rote Umrandung, wenn der Button gedrückt wird
void waitForIt(int x1, int y1, int x2, int y2)
{
  myGLCD.setColor(255, 0, 0);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
  while (myTouch.dataAvailable())
    myTouch.read();
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
}

//Aufbau der Startseite
void startseite()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 0, 0, 237);
 myGLCD.fillRect(0, 0, 239, 12);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Startseite by Knippi", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);
   myGLCD.setFont(Sinclair_M);
  myGLCD.print("Startseite", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
    myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
  waitForTouch();
   
}

//Aufbau der Menueseite
void menue()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  //myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(255, 255, 0);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 255, 255, 0);     //setzt die Farbe des Farbbalkens oben
 myGLCD.fillRect(0, 0, 239, 13);  //setzt die Größe und Position des Hintergrundes des Balkens oben
  myGLCD.setColor(0, 0, 0);       //setzt die Schriftfarbe für den nachfolgenden Text
  myGLCD.print("Menue", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);   //setzt die Schriftfarbe für den nachfolgenden Texte
   myGLCD.setFont(Sinclair_M);
    myGLCD.setColor(255, 255, 255);
  myGLCD.print("Menue", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
   /* myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);*/
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
   //waitForTouch();
      myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (10, 60, 60, 10);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (10, 60, 60, 10);
     myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (60, 130, 10, 80);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (60, 130, 10, 80);
    //myGLCD.print("1", 28, 27);
// waitForTouch();   
  waitForIt(10, 10, 60, 60);
}

//Aufbau der Settingseite
void setting()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(255, 0, 0);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 255, 0, 0);     //setzt die Farbe des Farbbalkens oben
 myGLCD.fillRect(0, 0, 239, 12);  //setzt die Größe und Position des Hintergrundes des Balkens oben
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Einstellungen", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);
   myGLCD.setFont(Sinclair_M);
  myGLCD.print("Einstellungen", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
  /*  myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);*/
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
   //waitForTouch();
     myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (10, 60, 60, 10);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (10, 60, 60, 10);
    //myGLCD.print("1", 28, 27);
// waitForTouch();  
  waitForIt(10, 10, 60, 60);

}

void loop ()
{
 if (myTouch.dataAvailable())  {
  
   mode = (mode + 1) % MODE_COUNT;
}
  
 
  if (mode == 0) {
  startseite();
} else if (mode == 1) {
  menue();
} else if (mode == 2) {
  setting();


}}

Gruß Jens

 if (myTouch.dataAvailable())  {
  
   mode = (mode + 1) % MODE_COUNT;
}

Das wird wahrscheinlich nicht funktionieren. Es sagt aus, dass sobald Daten von der Touch-Schnittstelle zur Verfügung stehen, wird der Modus weitergeschaltet. Das dürfte durchgehend der Fall sein, denn die Daten werden ja nicht ausgelesen. Somit schaltet er in viel zu schneller Folge durch. Soweit ich mich an das API erinnern kann, ist das nicht so gedacht.

Ich würde so etwas wie das hier erwarten (nur als Beispiel):

      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if ((y>=10) && (y<=60) &&  // vertikaler Abstand (von oben)
               (x>=179) && (x<=239)) {  // horizontaler Abstand (von rechts)

OK. Aber das sagt doch aus, dass man genau auf diesen Punkt bzw. Bereich einer Fläche drücken muss. Nämlich ungefähr oben links. Bei der ersten Seite sollte es aber so sein, egal wo auf dem Touchfeld ich drücke soll es eine Seite(menue) weiterspringen.
Was ist denn mit der Abkürzung API gemeint?

Soweit ich mich an das API erinnern kann, ist das nicht so gedacht.

Gruß Jens

Was ist denn mit der Abkürzung API gemeint?

API = Application Programmer Interface, also die Art und Weise, wie eine Bibliothek aus einem Programm heraus angesprochen wird (welche Parameter, welche Funktionsnamen, etc.)

Bei der ersten Seite sollte es aber so sein, egal wo auf dem Touchfeld ich drücke soll es eine Seite(menue) weiterspringen.

Trotzdem musst Du zumindest die Werte auslesen, damit Du nicht in der Schleife festsitzt.

Ich kenne Deine Anforderungen nicht, aber wenn der Wechsel-Button immer woanders ist, dann kannst Du ja die Position in einem Array festhalten:

uint8_t buttonRect[MODE_COUNT][4] = { { 0, 0, 250, 100 }, 
                                      { 179, 10, 239, 60 },
                                      { 140, 30, 200, 40 }};

void loop() {
  if (myTouch.dataAvailable()) {
    myTouch.read();
    x = myTouch.getX();
    y = myTouch.getY();
    if (x >= buttonRect[mode][0] && y >= buttonRect[mode][1] &&
          x <= buttonRect[mode][2] && y <= buttonRect[mode][3]) {
      mode = (mode + 1) % MODE_COUNT;
    }
  }
// ...
}

Hallo pylon,
es will einfach nicht. Ich habe beides ausprobiert. Ich beschreibe es einmal:
Die Startseite wird angezeigt>drücke ich auf das Display>springt das Display wieder auf die Startseite.
Gruß Jens

Nun habe ich noch ein wenig experimentiert und es gibt einen kleinen Fortschritt.
Mit dem nachfolgenden Sketch ergibt sich folgendes Ergebnis:
Als erstes startet ein leerer Bildschirm>drücke ich links/oben auf die angegeben Position dann springt das Display auf die "menue" Seite(schon mal gut :))>drücke ich dann wieder links/oben, dann springt das Display auf die "setting" Seite(noch besser :D)>>drücke ich dann wieder links/oben, dann springt das Display auf die "startseite" Seite zurück(juhu:grin:)>>drücke ich dann wieder links/oben, dann springt das Display wieder auf die "menue" Seite(geschafft :open_mouth:)...
Alles soweit ganz gut, nur wird die Startseite nicht als erstes Angezeigt sondern eine leere Seite. ]:smiley:

#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <avr/pgmspace.h>
#define MODE_COUNT 3

// Schriftarten in Benutzung
extern uint8_t SmallFont[];
extern uint8_t Sinclair_S[];
extern uint8_t Sinclair_M[];
extern uint8_t BigFont[];


//Pinbelegung für das Display+Touchscreen
//myGLCD(RS,WR,CS,RST,ALE,mode);
ITDB02 myGLCD(A1,A2,A0,A3,A5,ITDB32S);
//myTouch(TCLK,TCS,DIN,DOUT,IRQ);
ITDB02_Touch  myTouch(13,10,11,12,A4);


int x, y;
int mode = 0;

void setup()
{
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(Sinclair_S);

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_LOW);
}

 
  //zeichnet eine rote Umrandung, wenn der Button gedrückt wird
void waitForIt(int x1, int y1, int x2, int y2)
{
  myGLCD.setColor(255, 0, 0);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
  while (myTouch.dataAvailable())
    myTouch.read();
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
}
  
//Aufbau der Startseite
void startseite()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 0, 0, 237);
 myGLCD.fillRect(0, 0, 239, 12);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Startseite by Knippi", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);
   myGLCD.setFont(Sinclair_M);
  myGLCD.print("Startseite", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
    myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
  
}
   
   //Aufbau der Menueseite
void menue()
{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  //myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(255, 255, 0);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 255, 255, 0);     //setzt die Farbe des Farbbalkens oben
 myGLCD.fillRect(0, 0, 239, 13);  //setzt die Größe und Position des Hintergrundes des Balkens oben
  myGLCD.setColor(0, 0, 0);       //setzt die Schriftfarbe für den nachfolgenden Text
  myGLCD.print("Menue", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);   //setzt die Schriftfarbe für den nachfolgenden Texte
   myGLCD.setFont(Sinclair_M);
    myGLCD.setColor(255, 255, 255);
  myGLCD.print("Menue", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
   /* myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);*/
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
   //waitForTouch();
      myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (10, 60, 60, 10);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (10, 60, 60, 10);
     myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (60, 130, 10, 80);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (60, 130, 10, 80);
}
    
    //Aufbau der Settingseite
void setting()

{
  myGLCD.setColor( 0, 0, 0);  //setzt die Farbe im Hintergrund
  myGLCD.fillRect(0, 0, 239, 320);  //setzt die Größe und Position des Hintergrundes
  myGLCD.setColor(255, 255, 255);  //setzt die Schriftfarbe
  myGLCD.setBackColor(255, 0, 0);  //setzt die hinterleget Farbe des Textes 
  myGLCD.drawLine(0, 14, 239, 14); //setzt die Position und Länge der Linie
  myGLCD.setColor( 255, 0, 0);     //setzt die Farbe des Farbbalkens oben
 myGLCD.fillRect(0, 0, 239, 12);  //setzt die Größe und Position des Hintergrundes des Balkens oben
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Einstellungen", CENTER, 3);
  myGLCD.setBackColor(0, 0, 0);
   myGLCD.setFont(Sinclair_M);
  myGLCD.print("Einstellungen", CENTER, 30);
   myGLCD.setFont(Sinclair_S);
  /*  myGLCD.setBackColor(0, 0, 237);  //setzt die hinterleget Farbe des Textes
  myGLCD.print("Touch screen to continue", CENTER, 305);*/
   myGLCD.setBackColor(0, 0, 0);  //setzt die hinterleget Farbe des Textes
   myGLCD.print("jens.knipphals@gmx.de", CENTER, 290);
   //waitForTouch();
     myGLCD.setColor(0, 0, 255);
    myGLCD.fillRoundRect (10, 60, 60, 10);
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRoundRect (10, 60, 60, 10);
}
    
    void loop ()
{
  
 if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if ((y>=10) && (y<=60))  // vertikaler Abstand (von oben)
      {        if ((x>=179) && (x<=239))  // horizontaler Abstand (von rechts)
        
          waitForIt(10, 10, 60, 60); //Größe des roten Umrandung
  
   mode = (mode + 1) % MODE_COUNT;
 }
  
 
  if (mode == 0) {
  startseite();
} else if (mode == 1) {
  menue();
} else if (mode == 2) {
  setting();


}}}

Gruß Jens

Nimm die IF-Anweisung mit der Touch-Erkennung im Loop nach den Teil, der die Ausgabe macht.

void loop() {
  if (mode == 0) {
    startseite();
  } else if (mode == 1) {
    menue();
  } else if (mode == 2) {
    setting();
  }
  if (myTouch.dataAvailable()) {
    myTouch.read();
    x = myTouch.getX();
    y = myTouch.getY();
    if (x >= buttonRect[mode][0] && y >= buttonRect[mode][1] &&
          x <= buttonRect[mode][2] && y <= buttonRect[mode][3]) {
      mode = (mode + 1) % MODE_COUNT;
    }
  }
}

Du solltest Deinen Code besser formatieren. Im Moment ist er äusserst schlecht lesbar. Die IDE hat eine Funktion dafür, in der englischen Version unter "Tools/Auto Format" (Ctrl-T).

Hallo pylon,
das hat leider nicht funktioniert. Es startete zwar mit der Startseite, diese startete aber immer wieder neu und wiederholte sich ununterbrochen.
Ich habe nun ein paar Nächte herumprobiert und habe ein Ergebnis gefunden, dass so aussieht:

uint16_t buttonRect[MODE_COUNT][5] = { 
  { 
    0, 0, 239, 320       }
  , 
  { 
    209, 80, 229, 100       }
  ,
  { 
    140, 30, 200, 40       }
  ,
  { 
    100, 30, 160, 40       }
};

void loop ()
{
  startseite();
  while (true)

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();
      if (x >= buttonRect[mode][0] && y >= buttonRect[mode][1] &&
        x <= buttonRect[mode][2] && y <= buttonRect[mode][3]) {
        mode = (mode + 1) % MODE_COUNT;
        //waitForIt(30, 80, 20); //Größe des roten Umrandung
      }


      if (mode == 0) {
        startseite();
      } 
      else if (mode == 1) {
        menue();
      } 
      else if (mode == 2) {
        setting();
      } 
      else if (mode == 3) {
        testseite();  

        delay(10); 

      }
    }
}

Dieser Ablauf funktioniert auch, aber ich bin auf ein Problem gestoßen. Es sollte eine Menueführung mit weiteren Untermenues geben, so das diese nicht alle nacheinander aufgerufen werden sollen. Bei dieser Version kann ich so wie ich es erkenne nur eine Seite nach der anderen Aufrufen. Quasi wie eine Kette, richtig?
Ich brauche aber einen teilweise direkten Aufruf einer Seite, die dann auch meinetwegen aufeinanderfolgende Untermenues(z.B. Timer 1-12) hat. Des halb habe ich in meinen anfänglichen Sketch versucht alle Seiten direkt über verschiedene Button zu Starten. Ich habe mal die Struktur skizziert und als Bild mit angehängt.
Gruß Jens

Hallo Knippi,
ich bin selber Newbie hier und versuche mich gerade an einer ähnlichen Aufgabe wie du.
Vielen Dank an Pylon, deine Lösungen sind sehr elegant.
Als Neuling überfordern sie mich noch ein wenig, da ich mich mit Arrays noch nicht beschäftigte.
Ich finde es toll das du dir Zeit nimmst uns Newbies etwas zu erklären. :slight_smile:
@Knippi für mein erstes Menue half mir dieser Link : SobiSource.com is for sale | HugeDomains
Ich hoffe er kann auch dich inspirieren.

Hallo 2curious,
danke für deinen Beitrag. Es hilft Einsteigern wie uns durch die Erklärungen und die direkten praktischen Lösungen zu unseren Problemen, nach und nach das ganze zu Verstehen und zu Erlernen. Ich für meinen Teil habe an diesem Projekt eine ganze Menge gelernt.
Die Hilfestellung von pylon war super und die Menue-Steuerung auf meinem Touchscreen funktioniert. Nur leider kann man mit diesem Sketch nur nacheinander folgende Seiten/Menuepunkte abarbeiten. D.h. man startet mit der 1. Seite und bei einem "Touch" auf dem Display springt diese auf die nächste Seite/Auswahlseite(Menue), bis es dann je nach dem wie viel Seiten im Sketch eingestellt wurden, irgendwann wieder auf die 1. Seite zurück springt und alles beginnt von vorn.
Ich benötige aber die Möglichkeit, von der 1. Seite auf die nächste Seite zu springen, um von dort aus auf einen bestimmte Seite zu springen und wieder zurück zur vorherigen Seite oder zu der Auswahlseite nach der 1. Seite. Es ist also wie eine Baumstruktur oder auch Verzeichnisstruktur.
Ich habe das in dem Beitrag #14 mal als Zeichnung mit angehängt.
Leider bekomme ich von pylon z.Z. kein Reply mehr vielleicht ist er im Urlaub oder hat z.Z. keine Zeit.
Ich hoffe, es gibt hier im Forum noch andere die dazu noch etwas beitragen können.
Vielleicht gab es ja schon ein ähnliches Projekt. Nur ist es dann immer so eine Sache in dem Projekt als Neuling einzusteigen, ohne Hilfestellung.

@Knippi für mein erstes Menue half mir dieser Link : SobiSource.com is for sale | HugeDomains
Ich hoffe er kann auch dich inspirieren.

Das von dir gelinkte Projekt, ist eigentlich genau das richtige. Nur leider ist in dem Sketch noch soviel anderer "Schnickschnack", den ich wieder als Neuling nicht verstehe. Auch bin ich nicht so gut im Englischen.
Vielleicht gibt es hier ja jemand im Forum der nur diesen von mir beschriebenen Teil rausfiltern kann und mir dann noch ein wenig Hilfestellung geben kann. Auch wäre ich dankbar, wenn ich dann noch die ein oder andere Frage beantwortet bekomme um das ganze dann wieder zu verstehen.

ich bin selber Newbie hier und versuche mich gerade an einer ähnlichen Aufgabe wie du.

Nun aber nicht nur über mein Problem mit meinem Projekt gequatscht, was für ein ähnliches Projekt bis du am Basteln?

Gruß Jens

Hallo Knippi,

mein Projekt soll mal eine Kombination aus programmierbarer Infrarotfernsteuerung und DMX Lichtsteuerung werden... das wird noch ein langer Weg XD
Auf deine Anregung hin habe ich meinen Sketch (inspiriert durch Jeremy From thecustomgeek.com) so umgeschrieben das er nur eine Menue Struktur enthält. (s. Anhang)
Mich würde es freuen dir und anderen damit weiterhelfen zu können.
Der Sketch bietet 8 Menue Einträge mit jeweils 8 Untermenues, in dieser Version sind nur die Untermenues von Menue 1 vorhanden. Die "Up" und "Down" Tasten sind noch in den Kinderschuhen.
Es ist eine Anfänger Omega Version, aber im Prinzip funktioniert sie.
Je mehr ich mich damit beschäftige bemerke ich vieles ist eleganter zu lösen.
Als Anfänger ist es einfacher viele bekannte Befehle zu schreiben :grin:
Zu verbessern wären : (wenn ich wüsste wie)

  • Arrays für die Positionen von Schriften und Grafiken (es nervt 20 Einträge von Hand zu ändern)
  • Strings für wiederkehrende Anzeigen verwenden (s. Arrays)
  • mehr Abläufe in Funktionsaufrufe zu fassen

Gruß 2Curious

Menue_test.ino (15.4 KB)