utft code issues

hi there
im still new to using utft, what im trying to do at the moment is to have a start up screen which says pc controller which works fine then, to go to a main screen which comes up saying main screen, now this is when my problem occurs as when you tap the screen anywhere it will take me to a menu area which just has two boxes in at the moment which it does but the previous title saying “main screen” stays there and i dont know how to have a button in there to return to the main screen. i presume how im writing my code is not the best way of writing it, but dont really know to write it in any other way.
any help/examples would be appreciated.
thanks Joe

here is what i have at the moment

#include <UTFT.h>
#include <ITDB02_Touch.h>
// Declare which fonts we will be using
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Uncomment the next line for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!
ITDB02_Touch  myTouch(6,5,4,3,2);

int x, y;
char stCurrent[20]="";
int stCurrentLen=0;
char stLast[20]="";

void setup()
{

  // Setup the LCD
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(BigFont);

  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_MEDIUM);

  myGLCD.print("PC CONTROLLER", CENTER, 303);
    delay(3000);
  myGLCD.clrScr();
    delay(2000);
    myGLCD.setBackColor(0,100,255); // Set the background color to blue
    myGLCD.fillScr(0,100,255);      // Fill the screen with blue

}

void loop()
{
      //                               L,R   up, down
  myGLCD.print("Main Screen", CENTER, 300);
  
  if (myTouch.dataAvailable())
  {
    myTouch.read();
    y=myTouch.getY();

    if ((y>=0) && (y<=300))  
      {
  myGLCD.clrScr();
  myGLCD.fillScr(0,100,255);      // Fill the screen with blue

    //                 T,L  B,L  T,R  B,R  
  myGLCD.drawRoundRect(50,100,100,170);        // Draw a rectangle
  myGLCD.drawRoundRect(220,100,270,170);        // Draw a rectangle
      }

    }

  }

Can you find the full stop on the keyboard? It is right next to the comma on mine :slight_smile:

I would start by putting the things you want to do (ie, each screen of information) in a separate function that clears the screen and then does what it needs to do. You can the use the loop() function to coordinate between the different functions to move around.

You will need to learn how to program wihtout using the delay functions (the technique is shown in the BlinkWithoutDelay example) so that you can 'run' the user interface. The loop() function then is able to 'do' stuff in the background while the user makes up their mind what they want.

ok and thanks for your reply

do we no where i can get some information on function what is relatively easy to understnd?

and does any one no any better language to control this utft or know of any good links to get ideas from?

thanks

ok i have had a bit of a play and have come up with this but i still dont no what to do in the loop for the uTouch( were i have put dont no what to do here???) any ideas or suggestions?

#include <UTouchCD.h>

// UTFT_Demo_320x240 

#include <UTFT.h>
#include <UTouch.h>
// Declare which fonts we will be using
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Uncomment the next line for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!
UTouch  myTouch(6,5,4,3,2);

int x, y;
char stCurrent[20]="";
int stCurrentLen=0;
char stLast[20]="";

void setup()
{

  // Setup the LCD
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(BigFont);

  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_MEDIUM);

  myGLCD.print("PC CONTROLLER", CENTER, 303);
  delay(3000);
  myGLCD.clrScr();
  delay(2000);

  MainScreen(0, 0, 0, 0);
}

void loop()
{
    while (true)
  {
  if (myTouch.dataAvailable())
  {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      ScreenTo(0, 0, 300, 300);            //
                                                       //   dont no what to do here??????
      MainScreen(50, 100, 100, 170);   //
   }
  }
}


void MainScreen(int x1, int y1, int x2, int y2){
  myGLCD.clrScr();
  //                               L,R   up, down
  myGLCD.print("Main Screen", CENTER, 300);

}


void ScreenTo(int x1, int y1, int x2, int y2){
  myGLCD.clrScr();
  //                 T,L  B,L  T,R  B,R  
  myGLCD.drawRoundRect(50,100,100,170);        // Draw a rectangle
  myGLCD.print("M", 54, 385);

}
  if (myTouch.dataAvailable())
  {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      ScreenTo(0, 0, 300, 300);            //
                                                       //   dont no what to do here??????
      MainScreen(50, 100, 100, 170);   //
   }

All that this code does is read the x and y coordinates and then do screen 1 followed by screen 2. YOu need to put some logic in place to determine which ‘button’ has been pressed and then call the right screen - once you have x and y you need to check ofthe touch is in the ‘button’ area for each menu item. I don’t know what size your buttons are, so you will need to change the code below:

 {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if (x>=BUTTON1_XMIN && x<= BUTTON1_XMAX && y>= BUTTON1_YMIN && y<=BUTTON1_YMAX)
      {
         ScreenTo(0, 0, 300, 300);            //
      }

      if (x>=BUTTON2_XMIN && x<= BUTTON2_XMAX && y>= BUTTON2_YMIN && y<=BUTTON2_YMAX)
      {
        MainScreen(50, 100, 100, 170);   //
      }
   }

Generally, howebver, you code needs to be reorganised or you will come into trouble. For example, you do not draw the button on the screen, so how does the user know where to press? Once you exit from ScreenTo or Menu, what happens next (maybe this will be completed later?).

thanks for your exanple
this is all now to me, i have changed that exanple to this:

 if (myTouch.dataAvailable())
      {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if (50>=MainScreen && 100<= MainScreen && 100>= MainScreen && 170<MainScreen)
      {
         ScreenTo(0, 0, 300, 300);            //
      }

      if (0>=ScreenTo && 0<= ScreenTo && 300>= ScreenTo && 300<=ScreenTo)
      {
        MainScreen(50, 100, 100, 170);   //
      }
    }

this come’s up with errors so i’m doing something obviously wrong??

Generally, however, you code needs to be reorganised or you will come into trouble. For example, you do not draw the button on the screen, so how does the user know where to press? Once you exit from ScreenTo or Menu, what happens next (maybe this will be completed later?).

yes there is a lot more to be added yet im just trying to understand how this works and how to write things before i get too complicated

It would be helpful if you could include the actual error message?

      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if (50>=MainScreen && 100<= MainScreen && 100>= MainScreen && 170<MainScreen)
      {
         ScreenTo(0, 0, 300, 300);            //
      }

What is the variable MainScreen and where is it declared? I would have thought you should be comparing 50, 100, 170, etc to the variables x and y, which contain the coordinates you read form the touchscreen.

I would suggest that you should start on simpler examples of how to use variables and structure code. The examples that come with the Arduino IDE are a good place to read and understand how some of these basic concepts work. Once you have done that, maybe attempt this project, which is more complex.

It would be helpful if you could include the actual error message?

yes sorry i should have done

pc_control_x2.cpp: In function 'void loop()':
pc_control_x2:48: error: 'BUTTON1_XMIN' was not declared in this scope
pc_control_x2:48: error: 'BUTTON1_XMAX' was not declared in this scope
pc_control_x2:48: error: 'BUTTON1_YMIN' was not declared in this scope
pc_control_x2:48: error: 'BUTTON1_YMAX' was not declared in this scope
pc_control_x2:53: error: 'BUTTON2_XMIN' was not declared in this scope
pc_control_x2:53: error: 'BUTTON2_XMAX' was not declared in this scope
pc_control_x2:53: error: 'BUTTON2_YMIN' was not declared in this scope
pc_control_x2:53: error: 'BUTTON2_YMAX' was not declared in this scop

i gather the problem is that i have not declared anything?

What is the variable MainScreen and where is it declared? I would have thought you should be comparing 50, 100, 170, etc to the variables x and y, which contain the coordinates you read form the touchscreen.

yes looks like i got my numbers mixed up
how do i declare it or how do i word it?

yes i do need a biy more practice

int BUTTON1_XMIN = 0;
int BUTTON1_XMAX = 0;
int BUTTON1_YMIN = 0;
int BUTTON1_YMAX = 0;

int BUTTON2_XMIN = 0;
int BUTTON2_XMAX = 0;
int BUTTON2_YMIN = 0;
int BUTTON2_YMAX = 0;

am i getting there lol
it now compiling but the touch does not work?

Think about what the values of the variables should be. Their names is a big clue.

ahh yes i see so ive changed my 0 out for the numbers of the coordinates and now my touch is working again but my next issue is now when i tap the screen to go to ScreenTo it goes to it and immediately goes straight back to main screen.

Are your buttons overlapping?

yes but they are on two different screens
so in other words main screen will be just a screen to give you general information, then if you tap the screen anywhere it will take you to screen two which will be a menu screen which you can go onto other functions in the future

Unless you are reading two physically separate touchscreens, which does not seem to be the case in your code, you should only check the button depending on which screen is being displayed. Otherwise you are checking for all the buttons all the time, no matter what screen is being displayed.

you should only check the button depending on which screen is being displayed

how do i go about doing that?

When you display a screen, set a variable to say that that screen is being displayed. Then whe nyou are checking the buttons, if the variable says screen x, then check for thethe buttons for screen x, if screen y, then the buttons for screen y, etc.

You need to use an if statement to make the selection of which logic to use at the time.

i’d love to elaborate on the structure of what you should be close to, but i cannot get even the simple demos to compile. I keep getting compiler errors like: sketch_today:22: error: ITDB02_Touch does not name a type, cause of error:

#include <UTFT.h>
#include <ITDB02_Touch.h>
// Declare which fonts we will be using
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];


// Uncomment the next line for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);   
ITDB02_Touch  myTouch(6,5,4,3,2);

ironically in this snippet example the myGLCD didnt throw an error, but ITDB02_Touch & myTouch did. My question is: How would I go about declaring “ITDB02_Touch myTouch(6,5,4,3,2)” as a type?

ITDB32S Mega
Mega 2560 ADK
Arduino 1.03

When you display a screen, set a variable to say that that screen is being displayed. Then whe nyou are checking the buttons, if the variable says screen x, then check for thethe buttons for screen x, if screen y, then the buttons for screen y, etc.

You need to use an if statement to make the selection of which logic to use at the time.

yes ok im struggling to get started, you couldnt give me a kick start in the right direction?
thanks for your help so far

Arduino 1.03

i tried mine on 1.0 but couldnt get it to work so i tried it on 2200 and worked fine ever since

#include <UTouchCD.h>

// UTFT_Demo_320x240 

#include <UTFT.h>
#include <UTouch.h>
// Declare which fonts we will be using
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Uncomment the next line for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!
UTouch  myTouch(6,5,4,3,2);

uint8_t curScreen = 0;

void setup()
{
  // Setup the GLCD
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(BigFont);

  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_MEDIUM);

  myGLCD.print("PC CONTROLLER", CENTER, 303);
  delay(3000);
}

void loop()
{
  switch (curScreen)
  {
  case 0:
    MainScreen(50, 100, 100, 170);
    break;

  case 1:
    ScreenTo(0, 0, 300, 300);
    break;

  default:
    curScreen = 0; // restart if anything goes wrong
  }
}


bool checkButtonPressed(int X1, int y1, intX2, int y2)
{
  if (myTouch.dataAvailable())
  {
      int x,y;
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();

    if ((x>=x1) && (x<=x2) && (y>=y1) && (y<=y2))
      return(true);
  }

  return(false);
}


void MainScreen(int x1, int y1, int x2, int y2)
{
  static bool bInitialised = false;

  if (!bInitialised)
  {
    myGLCD.clrScr();
    //                               L,R   up, down
    myGLCD.print("Main Screen", CENTER, 300);
    myGLCD.drawRoundRect(x1, y1, x2, y2);        // Draw a rectangle
    bInitialised = true;
  }
  else 
  {
    if (CheckButtonPressed(x1, y1, x2, y2)) 
    {
      curScreen = 1;
      bInitialised = false;
    }
  }
}


void ScreenTo(int x1, int y1, int x2, int y2)
{
  static bool bInitialised = false;

  if (!bInitialised)
  {
    myGLCD.clrScr();
    //                 T,L  B,L  T,R  B,R  
    myGLCD.drawRoundRect(x1, y1, x2, y2);        // Draw a rectangle
    myGLCD.print("M", 54, 385);
    bInitialised = true;
  }
  else 
  {
    if (CheckButtonPressed(x1, y1, x2, y2)) 
    {
      curScreen = 0;
      bInitialised = false;
    }
  }
}

You’ll need to make sure it compiles and then debug the logic, as I am nowhere near anything that allows me to do that, but you have the basics in this code.

To OP:

This is something I’ve been playing with, but tried to abstract the button code out into a standalone library. Feel free to play with the following code:-

GadgetTest.ino

#include <SSD1289.h>
#include <UTouch.h>
#include "Gadgets.h"

SSD1289 disp(38,39,40,41);
UTouch  myTouch(6,5,4,3,2);

extern uint8_t SmallFont[];

Gadgets Gadgets;
boolean FirstPass = true;

void setup()
{
  Gadgets::scr = & disp;
  Gadgets::touch = & myTouch;
  
  Serial.begin(9600);
}

Button but[8];

void loop()
{
  int l;
  
  if (FirstPass)
  {
    FirstPass = false;
   disp.InitLCD();
   disp.clrScr();

   but[0].SetUp(20,20,100,40,"Test 1",STANDARD,SmallFont);
   but[1].SetUp(20,80,100,40,"Test 2",STANDARD,SmallFont);
   but[2].SetUp(20,140,100,40,"Test 3",STANDARD,SmallFont);

 }
 else
 {
   for (l=0; l<=2; l++)
   {
     if (but[l].Handle() == BUTTON_PRESSED)
     {
       Serial.print(but[l].label);
       Serial.print(" pressed\n");
     }
   }
   
 }
 
}

Gadgets.h:

#include <SSD1289.h>
#include <UTouch.h>

#ifndef Gadgets_H
#define Gadgets_H

class Gadgets
{
    public:    
      static SSD1289 *scr;  
      static UTouch  *touch;

      Gadgets();
      void Iterate();
      int TouchX;
      int TouchY;
      boolean TouchPressed;
      boolean LastTouchPressed;
   private:
      int      LastSample; 
      boolean  TouchFirstPass; 
    
};

     

typedef enum tButtonMode {STANDARD};
typedef enum tAction { INITIAL,       // Basic initialisation (parameters) set, needs to be rendered
                       INITIALISED};  // Initialised and rendered, needs to be managed on a cyclic basis
typedef enum tStatus { NO_ACTION,
                       BUTTON_PRESSED };
typedef enum tButtStatus { BUTT_NOT_PRESSED,
                           BUTT_PRESSED };
class Button : Gadgets
{
  public:
    Button();
    Button(int XPosition, int YPosition, int Width, int Height, char *Label, tButtonMode Mode, uint8_t *Font);
    void SetUp(int XPosition, int YPosition, int Width, int Height, char *Label, tButtonMode Mode, uint8_t *Font);
    tStatus Handle();
    char *label;
    
  private:
    void Render();
    boolean defined;
    tAction action;
    tButtStatus buttstatus;
    int x,y,w,h;
    uint8_t * font;
    tButtonMode mode;
    word col_highlight, col_background, col_shadow;
    boolean FirstPressedWithinButton;
    
};


#endif

and Gadgets.cpp

#include "Gadgets.h"
#include <SSD1289.h>
#include <UTouch.h>

SSD1289 *Gadgets::scr;
UTouch *Gadgets::touch;
//
//
//      T O U C H   S C R E E N
//
//
Gadgets::Gadgets()
{
  LastSample = 0;
  TouchFirstPass = true;
}
/*
Iterate()
---------
Provided this is called cyclically, this will ensure that the touch screen
controller is only scheduled every 100mS, or slower (depending on scheduling
rate).
*/
void Gadgets::Iterate()
{
  unsigned long time;
  if (TouchFirstPass)
  {
    TouchFirstPass = false;
    LastSample = millis();
    touch->InitTouch();
    touch->setPrecision(PREC_MEDIUM);
  }
  
  time = millis();
  
  if ((time - LastSample) >= 100)
  {
    LastTouchPressed = TouchPressed;
    
    LastSample = time;
    if (touch->dataAvailable() == true)    
    {
      touch->read();
      TouchX = touch->getX();
      TouchY = touch->getY();
      TouchPressed = true;
    }
    else
    {
      TouchPressed = false;
    }
  }
}


//
//
//
//    B U T T O N
//
//
//
Button::Button()
{
  defined = false;
}

Button::Button(int XPosition, int YPosition, int Width, int Height, char *Label, tButtonMode Mode, uint8_t *Font)
{
  SetUp(XPosition, YPosition, Width, Height, Label, Mode, Font);
}

void Button::SetUp(int XPosition, int YPosition, int Width, int Height, char *Label, tButtonMode Mode, uint8_t *Font)
{
  x = XPosition;
  y = YPosition;
  w = Width;
  h = Height;
  label = Label;
  mode = Mode;
  defined = true;
  action = INITIAL;
  buttstatus = BUTT_NOT_PRESSED;
  col_highlight  = 0xFFFF;//scr->RGBToWord(255,255,255);
  col_background = 0xCCCC;//scr->RGBToWord(128,128,128);
  col_shadow     = 0x9999;//scr->RGBToWord(64,64,64);
  font = Font;
}

void Button::Render()
{
  int text_x, text_y;
  
  if (defined)
  {
    switch (buttstatus)
    {
      case BUTT_NOT_PRESSED:
        scr->setColor(col_highlight);
        scr->drawLine(x,y,x+w-1,y);
        scr->drawLine(x,y+1,x,y+h-1);
        
        scr->setColor(col_background);
        scr->fillRect(x+1,y+1,x+w-2,y+h-2);

        scr->setColor(col_shadow);
        scr->drawLine(x+1,y+h-1,x+w-1,y+h-1);
        scr->drawLine(x+w-1,y+1,x+w-1,y+h-2);
        break;
      case BUTT_PRESSED:
        scr->setColor(col_shadow);
        scr->drawLine(x,y,x+w-1,y);
        scr->drawLine(x,y+1,x,y+h-1);
        
        scr->setColor(col_background);
        scr->fillRect(x+1,y+1,x+w-2,y+h-2);

        scr->setColor(col_highlight);
        scr->drawLine(x+1,y+h-1,x+w-1,y+h-1);
        scr->drawLine(x+w-1,y+1,x+w-1,y+h-2);
        break;
    }
    
    scr->setBackColor(col_background);
    scr->setColor(col_highlight);
    scr->setFont(font);
    
    text_x = x + w/2 - (scr->getFontXsize() * strlen (label) / 2) ;
    text_y = y + h/2 - (scr->getFontYsize() /2 );
    
    scr->print(label,text_x,text_y);
    
  }  
}

tStatus Button::Handle()
{
  tStatus status = NO_ACTION ;
  switch (action)
  {
    case INITIAL:
      action = INITIALISED;
      Render();
      break;
    case INITIALISED:
      Iterate();
      
      if (TouchPressed)
      {
        if (!LastTouchPressed)
        {
          // Action when the touch screen is FIRST pressed
          if (TouchX >= x && TouchX <= x+w && TouchY >= y && TouchY <= y+h)
          {
            // touch screen was first pressed within the bounds of this button
            FirstPressedWithinButton = true;
            buttstatus = BUTT_PRESSED;
            Render();
          }
          else
          {
            // touch screen was pressed outside the bounds of this button - ignore all future movements
            FirstPressedWithinButton = false;
          }
        }
        else
        {
          // Action whilst the screen is held
          if (FirstPressedWithinButton)
          {
            // Only process if the screen was originally pressed within the button
            if (TouchX >= x && TouchX <= x+w && TouchY >= y && TouchY <= y+h)
            {
              if (buttstatus != BUTT_PRESSED)
              {
                buttstatus = BUTT_PRESSED;
                Render();
              }
            }
            else
            {
              if (buttstatus != BUTT_NOT_PRESSED)
              {
                buttstatus = BUTT_NOT_PRESSED;
                Render();
              }
            }
            
          }
        }
      }
      else
      {
        if (LastTouchPressed && FirstPressedWithinButton)
        {
          // Screen has just been released... 
          if (buttstatus == BUTT_PRESSED)
          {
            status = BUTTON_PRESSED;
          }
          
          buttstatus = BUTT_NOT_PRESSED;
          Render();          
        }
      }
      break;

  }
  
  return status;
}

SSD1289 is simply an optimised version of UTFT - you can substitute that in it’s place. The code is very much a work-in-progress and I don’t pretend that it’s elegant, but it does implement a button class that requires you to press, and release the screen within the button boundaries to be recognised as a valid button selection. Lots of things to improve, but maybe some ideas within