Using TFT button for dual purposes

I am trying to use a touch screen circle that I have created with 2 functions. Like a 2 state button, button push and button hold.
The code below has the circles filled with green by default and switching to red when pressed.
Is it possible to have the color change only while the coords are touched?
I think a while statement would freeze the whole code at that stage.

outletState = digitalRead(OUTLETS[0]);
   if (outletState == LOW){
   myGLCD.setColor(0,255,0);           //outlets are default "ON"  
   myGLCD.fillCircle(101,51,11);       //Green Fill Circles will indicate this 
   }
   else if (outletState == HIGH){
   myGLCD.setColor(255,0,0);           //outlet "OFF"  
   myGLCD.fillCircle(101,51,11);       //Red Fill Circle will indicate this
   }

I was attempting with something like this

if (pumpcalibration == true){
    myGLCD.setColor(255,0,0);
    myGLCD.fillCircle(76,34,11);
    analogWrite(motorPin1, 0);
}
  if ((x>=75) && (x<=84)){
    if ((y>=34) && (y<=44)){
    myGLCD.setColor(0,255,0);
    myGLCD.fillCircle(76,34,11);
    analogWrite(motorPin1, 255);
    }

  }

Which changes the state okay but not only while held. Would this be possible?

Yea, of course, but you will need a latch.

Read the coords, if the button is pressed, and not held, change the button color and state.

Here is an example you can use, but instead of an actual button, you can use the touch screen coords.

byte LEDpin = 13; //on-board LED
byte ButtonPin = 2; //digital pin 2

boolean button,last = LOW;
boolean latch = false;

void setup() {
  pinMode(LEDpin, OUTPUT);
  pinMode(ButtonPin, INPUT);
}

void loop() 
{
  button = digitalRead(ButtonPin);
  if (button == HIGH && button != last) 
  {
    latch = !latch;
    latch ? digitalWrite(LEDpin, HIGH): digitalWrite(LEDpin, LOW);
  }
  last = button;
}

Or if you want, you can download my TFT library, where I have already done just that.
TFT_Extension.zip

You may need to change the libraries in my example sketches. I have the old ITDB02 libraries, but my TFT library should work with the ones you have. If not, then let me know and I'll tell you what to fix to get it to work.

Alright, I will attempt to use your library.
So I just import the TFT extension library into Arduino and then I should be able to open latching buttons for instance and change the libraries to mine and use it correct?
It doesnt seem to want to let me add it.
I went to sketch/import library/add library and selected the folder and nothing happened.
Should I add it manually?

Yea, try it. Look at one of the example sketches to see how to set it up.

I added it manually

This is the way I set the code up
It verifies okay but I get nothing on the screen at all.
Am missing 1 parameter for UTFT myGLCD compared to your code and the way I currently have it set up.

#include <UTouch.h>
#include <avr/pgmspace.h>
#include <UTFT.h>
#include <tinyFAT.h>
#include <UTFT_tinyFAT.h>
#include <EEPROM.h>
#include <RTClib.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <TFT_Extension.h>
#include <math.h>
// Declare which fonts we will be using
extern uint8_t SmallFont[];

//myGLCD(RS,WR,CS,RST,ALE,mode);
UTFT myGLCD(38,39,40,41,ITDB32S);
//myTouch(TCLK,TCS,DIN,DOUT,IRQ);
UTouch  myTouch(6,5,4,3,2);

TFT_Extension myTFT(&myGLCD, &myTouch, LANDSCAPE);

void setup()
{
  myGLCD.InitLCD(LANDSCAPE);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_MEDIUM);
  Serial1.begin(115200);
  startup();
}

void loop()
{   
  myTouch.read();
  int tx = myTouch.getX();
  int ty = myTouch.getY();
  int XC= tx > 320? 0 : tx; 
  int YC= ty > 240? 0 : ty;
  //data(XC,YC);
  getButton(XC,YC);
}

void startup()
{ 
  myGLCD.setColor(255, 0, 0);//red box fill
  myGLCD.fillRect(0, 0, 319, 13);//text box
  myGLCD.setColor(255, 255, 255);//text color White
  myGLCD.setBackColor(255, 0, 0);//background of text red
  myGLCD.drawLine(0, 14, 319, 14);
  myGLCD.print("LatchButtons", CENTER, 1);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("Touch screen to start", CENTER, 119);
  myGLCD.clrScr();
  makeButton();
}

void getButton(int tx, int ty){
  myGLCD.setColor(0,0,0);

  boolean me = myTFT.LatchCircle(55,180,50,0,tx,ty); // (x,y,radius, tx,ty)
  boolean me2 = myTFT.LatchCircle(265,55,50,1); // (x,y,radius, tx,ty)
  boolean button = myTFT.LatchButton(10,10,100,100,0,tx,ty);
  boolean button2 = myTFT.LatchButton(220,135,310,225,1);
  
  myGLCD.setBackColor(255, 255, 255);
  myGLCD.printNumI(me, 52,176);// circle button 1
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.printNumI(me2, 263,51); // circle button2
  myGLCD.setBackColor(0, 255, 0);
  myGLCD.printNumI(button, 50,50);// rect button 1
  myGLCD.setBackColor(0, 0, 255);
  myGLCD.printNumI(button2, 260,175);// rect button 2
}

void makeButton()
{
  myGLCD.setColor(255,255,255);
  myGLCD.drawCircle(55,180,50);// circle button 1
  myGLCD.setColor(255,0,0);
  myGLCD.fillCircle(265,55,50);// circle button 2
  myGLCD.setColor(0,255,0);
  myGLCD.drawRect(10,10,100,100);// rect button 1
  myGLCD.setColor(0,0,255);
  myGLCD.fillRect(220,135,310,225);// rect button 2
}

void data(int X, int Y)
{
  myGLCD.setBackColor(200, 0, 200);//background of text purple
  myGLCD.setColor(255,255,255);

  myGLCD.print("X: ", 100,115, 0);
  if(Y < 100){
    myGLCD.print("  ", 129,115, 0);
    myGLCD.printNumI(X, 124, 115);
  }
  else myGLCD.printNumI(X, 124, 115);

  myGLCD.print("Y: ", 180,115,0);
  if(X < 100){
    myGLCD.print("  ", 209,115, 0); 
    myGLCD.printNumI(Y, 204, 115);
  }
  else myGLCD.printNumI(Y, 204, 115); 
}

Nothing at all? Not even these?

myGLCD.setColor(255, 0, 0);//red box fill
myGLCD.fillRect(0, 0, 319, 13);//text box

This is incorrect,

UTFT myGLCD(38,39,40,41,ITDB32S);

It should be UTFT myGLCD(ITDB32S,38,39,40,41);

UTFT::UTFT(byte model, int RS, int WR,int CS, int RST, int SER)

Correct.
Now I get a red circle, blue box on right
Green outline box, white outline circle on left.Number 1 in the box, 2 in the circle
The numbers switch from 1 to 2 if I touch them.
Does that sound correct?
What I am not getting is text

? there boolean so it should be 0 and 1.

Being that my LCD and sketch uses the older library, there might be things that you need to set like text transparency.

Compare the sketch that came with the UTFT library to what I have, in my sketch. You should see text.

Hard to see but yeah I think you are right sorry.
So all 4 of them are switching from 0 to 1 is that what this example is meant to do?
So how do I make one change color only when it changes to 1 for instance?
Looking at the code I seem to be missing a bit also.
There is no text saying touch screen to start and no coordinates being printed either?

You would do it like so, put this after this line boolean button2 = myTFT.LatchButton(220,135,310,225,1);

  if (button2 != last) 
  {
    latch = !latch;
    if(latch)
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillRect(220,135,310,225);// rect button 1
    }
    else 
    {
      myGLCD.setColor(0,255,0);
      myGLCD.fillRect(220,135,310,225);// rect button 1
    }
  }
  last = button2;

The number in the center will still show as blue but you can disable the text by commenting it out.
I am still adding things to this library, so I will add this in it. You can follow the progress with this link.
New TFT_Extension

I got these errors
Latching_Buttons.ino: In function 'void getButton(int, int)':
Latching_Buttons:68: error: 'last' was not declared in this scope
Latching_Buttons:70: error: 'latch' was not declared in this scope
Latching_Buttons:82: error: 'last' was not declared in this scope

You need to add those at the top, they are boolean, here:

boolean last = LOW, latch = false;

Okay. Yeah that was stupid. I need to read the manual. :slight_smile:

I have got it right now.
However it is not entirely what I wanted. I was looking to have the state change only while pressed.
We have a color change but only as the state changes with another press.

So I think I need to add like a button release code as well, the same perhaps as a debounce and change the state on the release as well?

So instead of a latching button, change it to touch button, myTFT.TouchButton(220,135,310,225);

Perfect

Thanks for the excellent library and all your help.
Just need to get my limited mental resources to include it in my own sketch now and I will be unstoppable.

Thanks
Steve

Your welcome, I'm happy to hear my library was able to help you.

Okay clearly I am not capable of doing this on my own.
I tried to trim it down to the absolute minimum and remove the 4 images on the startup screen.
I am struggling to create a button on a circle on my page. The circle is already drawn.
Can you explain a little in laymans terms what is happening as you go down the code, particularly in relation to tx and ty

Ok, the same coordinates you use to draw/fill in the button/circle are the same ones you use to touch the circle. This way it is just simple copy and paste. The tx and ty are the actual touch data from,

myTouch.read();
int tx = myTouch.getX();
int ty = myTouch.getY();
int XC= tx > 320? 0 : tx;
int YC= ty > 240? 0 : ty;

Except in this case, your passing the fixed touch data XC and YC into the getButton function. You can actually do without the part above, and just have like this, boolean button2 = myTFT.LatchButton(220,135,310,225,1); Notice no tx or ty, thats because I actually implemented it into the library itself.

The only real reason you would use the function with tx and ty, is if you want to use the raw touch data from myTouch.TP_X and myTouch.TP_Y. This is actually faster but it requires you to map the screen and use the map function. Like this,

myTouch.read();
tx = myTouch.TP_X;
ty = myTouch.TP_Y;
XC = constrain(map(tx, 205, 3900,0,239),0,239); // raw touch data converted to pixel data
YC = constrain(map(ty, 300, 3850,0,319),0,319);//------------------------------------------

Oh and btw, the 1 in "LatchButton(220,135,310,225,1)" is a identification number, which as of right now, you can have 10 in total. You can have as many as you need, but you will need to change the value of this line in the .h file #define Num_Of_Buttons 10

My library doesn't draw or fill in the button when you add in the button functions, so you need to make those seperate, which is also why the sketch has a makeButton function.

void makeButton()
{
myGLCD.setColor(255,255,255);
myGLCD.drawCircle(55,180,50);// circle button 1

myGLCD.setColor(255,0,0);
myGLCD.fillCircle(265,55,50);// circle button 2

myGLCD.setColor(0,255,0);
myGLCD.drawRect(10,10,100,100);// rect button 1

myGLCD.setColor(0,0,255);
myGLCD.fillRect(220,135,310,225);// rect button 2
}

It is called in the setup function so it only runs once, but you can lock and unlock it if you ever need to remake the buttons.

I have a page called pumpcalibration

I have made this code

oid makeButton()
{
  if (pumpcalibration == true)
  myGLCD.setColor(255,0,0);
  myGLCD.fillCircle(79,39,11);// circle button 1
  myGLCD.setColor(0,255,0);
  myGLCD.fillCircle(79,39,50);// circle button 2

}

I know from my code using the serial monitor that 79,39 is roughly where my circle is drawn but when I upload and go to that page there is nothing there at all. Thats the part I am finding difficult to work out.