Go Down

Topic: Tochscreen-Display mit Menue-Steuerung (Read 3480 times) previous topic - next topic

Knippi

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.

Quote
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.

Code: [Select]
// 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);       
}}}}}}}

Knippi

Irgendwie fehlte da noch das eine Bild.
Anbei

Gruß Jens

pylon

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:

Code: [Select]
#define MODE_COUNT 3

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


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

Code: [Select]
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.

Knippi

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?
Code: [Select]
#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?
Code: [Select]
// 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?
Code: [Select]
if (buttonpress) {
  mode = (mode + 1) % MODE_COUNT;
}

Also so: und das für jeden Button einzeln?
Code: [Select]
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?
Code: [Select]
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
      }}}

Code: [Select]
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:
Code: [Select]
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. :smiley-eek-blue:
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.  :)
Vielen Dank, schon mal.
Gruß Jens

pylon

Quote
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.

Quote
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.

Quote
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

Quote
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:

Code: [Select]
mode = (mode + MODE_COUNT - 1) % MODE_COUNT;

Quote
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.

Quote
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.

Knippi

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:
Code: [Select]
int mode();
Was macht dieser Eintrag eigentlich?

Nun habe ich überlegt, was in diesem Teil passiert.
Quote
]if (myTouch.dataAvailable())  {
 
   mode = (mode + 1) % MODE_COUNT;
}


Hier wird doch der touch auf dem Bildschirm registriert und nachfolgend der mode berechnet. Richtig?
Quote
if (myTouch.dataAvailable())


Das Ergebnis von dem mode, müsste dann so aussehen:
Quote
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?
Quote
mode = (mode + 4) % MODE_COUNT;
mode= (0+3)/3
mode=1

Quote
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.
Code: [Select]
else if (mode == 1) {
  menue();
}

Gruß Jens

pylon

Quote
Was macht dieser Eintrag eigentlich?


Das müsste

Code: [Select]
int mode = 0;

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

Quote
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.

Quote
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.

Knippi

Hallo pylon,

ich habe
Quote
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.
Code: [Select]
// 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

pylon

Code: [Select]
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):

Code: [Select]
      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)

Knippi

#9
Aug 16, 2012, 02:20 pm Last Edit: Aug 16, 2012, 02:27 pm by Knippi Reason: 1
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?
Quote
Soweit ich mich an das API erinnern kann, ist das nicht so gedacht.

Gruß Jens

pylon

Quote
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.)

Quote
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:

Code: [Select]

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;
    }
  }
// ...
}

Knippi

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

Knippi

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:smiley-mr-green:)>>drücke ich dann wieder  links/oben, dann springt das Display wieder auf die "menue" Seite(geschafft :smiley-surprise:)...
Alles soweit ganz gut, nur wird die Startseite nicht als erstes Angezeigt sondern eine leere Seite. ]:D
Code: [Select]
#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

pylon

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

Code: [Select]
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).

Knippi

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:
Code: [Select]
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

Go Up