New TFT Extension Library

Please updated library in last REPLY.

I originally made this library for my own uses, but I feel it should be shared. It works with Henning Karlsen’s UTFT and UTouch libraries and it also works with his older ITDB02 libraries. “ITDB02_Graph16 and ITDB02_Touch”
PLEASE NOTE, I am still adding functions to this library (95% Done), mostly colors and functions that allow the user to choose there colors for certain functions like the drawTriangle function.
Right now I only have a 3.2 TFT Lcd that uses the older ITDB02 libraries, so all the examples will be set for those libraries, however, it does compile with the UTFT and UTouch examples.

TFT_Extension.zip (12.4 KB)

One comment: The implementation does NOT go in the header file. Include (accidentally) that library twice, and you'll have all kinds of error messages that are hard to decipher.

  double DIR = dir * 0.01745 + 1.57;

I hate magic numbers. You may know that they mean, but will everyone?

Ok, I changed DIR = dir * 0.01745 + 1.57; to DIR = dir * RAD_TO_DEG + HALF_PI;
Better yet:

double DIR = dir * RAD_TO_DEG;
Cx = x1 + sin(DIR + deg * RAD_TO_DEG + PI) * rad;
.
.
.

Whats is wrong with the implementation? It seems to work just fine.

What would be the better way? Make a .cpp file?

Whats is wrong with the implementation? It seems to work just fine.

As long as you are careful to only include it once in the whole program. Can you guarantee that your users will do that?

What would be the better way? Make a .cpp file?

Exactly.

Ok, I changed DIR = dir * 0.01745 + 1.57; to DIR = dir * RAD_TO_DEG + HALF_PI;

Now, that makes sense.

Can you guarantee that your users will do that?

No, not at all. But if (Big if) they do everything else fine, then the worst they will get is this:

CirclePad:14: error: redefinition of ‘TFT_Extension<ITDB02, ITDB02_Touch> myTFT’
CirclePad:13: error: ‘TFT_Extension<ITDB02, ITDB02_Touch> myTFT’ previously declared here

However it would help greatly if the Arduino software had visible line numbers on the side.

What would be the better way? Make a .cpp file?

Exactly.

By making a cpp file, I would need to include the UTFT and UTouch libraries, as well as the older ITDB02 libraries, right? What about if someone doesn’t have the older libraries, the compiler will want to know where they are.

I’ll figure it out.

@PaulS

Is there anyway I can make the precompiler detect if someone actually has the UTFT or UTouch libraries and then have the precompiler determine what lines to enable for the library to work?

HazardsMind: Is there anyway I can make the precompiler detect if someone actually has the UTFT or UTouch libraries and then have the precompiler determine what lines to enable for the library to work?

Yes & no, depends on where its used in the library. If you remember back to a previous post I helped you with; the method I used there was to detect the libraries and replace functionality. Remember this snippet:

struct MissingType{};

#ifdef LiquidCrystal_I2C_h 
  typedef LiquidCrystal_I2C LCDTYPE;
#else
  typedef MissingType LCDTYPE;
#endif

This method allows you to keep all your missing class stuff in one place, which would suit a well built template and not need to be modified at all. An alternative is to use:

#ifdef LiquidCrystal_I2C_h 
  #define USING_CLASS
#endif

But everywhere the class is used, you need to wrap its code in preprocessor tags to allow or prevent it from compiling:

#ifdef USING_CLASS
  //Class specific code.
#endif

Ah, ok I forgot about that. Thanks again Pyro.

Update: I added a new function, TextButton, and for right now, it will display text in the center of the button (the outline of the button still needs to be drawn separately) and you can still use it as a normal button. I am still working on the library and if I can get the TextButton function to work properly, I will do the same to the rest of the buttons.

I also added a wall ball game.

TFT_Extension.zip (15.7 KB)

Library updated. Added Connect Four game.

Note: I’m currently working on the AI for the connect four game and as of this version, the computer is really dumb. If you look at the function to play against the computer, you’ll see its just a few random functions and nothing else. So I am working on making it a bit more of a challenge, and so far it is going good.

After I get the AI to work, I am going to make the game wireless. Maybe not WiFi right now, because I don’t have a WiFi module, but it will definitely be Bluetooth.

TFT_Extension.zip (18.4 KB)

OK I got a nice little update on the library, I added quite a few new functions which may look confusing to use, but I provided example sketches on how to use them. I also a library description (.docx), hopefully it will clear up any questions.

New Functions:
*TouchButton_Draw *
*LatchButton_Draw *
*TouchCircle_Draw *
*LatchCircle_Draw *
TouchTriangle_Draw
LatchTriangle
LatchTriangle_Draw
*SetTouchButtonColors *
*SetTouchCircleColors *
*SetLatchButtonColors *
*SetLatchCircleColors *
*SetTouchTriangleColors *
SetLatchTriangleColors

The Connect Four game is nearly complete, I just need to fix the computers diagonal blocking algorithm and make it bluetooth capable.

I am still adding things to the library but at the length it is right now (+50 functions), there is still work to be done before I consider it complete.

There are a couple of sketches I provided that are still set to the old libraries but its not difficult to change them to the newer ones.

Try it out.

TFT_Extension.zip (37.3 KB)

do you have some test program to see the performance - footprint of the lib?

Hello I like your extension but I did reorganize your filestructure to the Default Arduino file structure so examples work right after you have copied the new lib into the libraries. File attached.

TFT_extension.zip (38.2 KB)

@robtillaart Not at the moment no. Actually what would be the best way to do that?

@Jeroi Thanks, I know the filing structure is bad, I didn't think anyone would mind it, but I will change it.

you could simply write a small sketch as a sample program that measures the time for every function. And yes some depend on the params e.g. fill square will be slower for large squares but the example sketch will run the same test for every display.

Radio button time track, 1 group of both types with 4 buttons each

#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <TFT_Extension_old.h>
#include <math.h>
// Declare which fonts we will be using
extern uint8_t SmallFont[];

// 
//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);

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

int cx, cy;
unsigned long timeStart, Total, timeCollect[9];
char * functs[11] = {
  "Setup TRB: ", "Setup TRCB: ", "Set RB colors: ", "Set RCB colors: ","1x RadioButton: ",
  "4x RadioButtons: ","1x RadioCircleButton: ",
  "4x RadioCircleButton: ", "Total Time: "};

void setup()
{
  myGLCD.InitLCD(LANDSCAPE);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_LOW);
  for(int line = 0; line <= 239; line++)
  {
    myGLCD.setColor(0, 0, line);//text color White  
    myGLCD.drawLine(0, line, 319, line);
  }
  Serial1.begin(9600);
  startup();
  getButton();
  myGLCD.clrScr();
  for(byte idx = 0; idx < 8; idx++)
  {
   myGLCD.print(functs[idx], 0, idx * 20);
   myGLCD.printNumF(timeCollect[idx], 200, idx * 20 );
   Total += timeCollect[idx] / 1000.00;
   myGLCD.printNumF(Total,3, 200, 200 );
  }
}

void loop() {}

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("ARDUINO RADIOBUTTONS", CENTER, 1);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("Touch screen to start", CENTER, 119);

  for(int line = 0; line <= 239; line++)
  {
    myGLCD.setColor(0, 0, line);//text color White  
    myGLCD.drawLine(0, line, 319, line);
  }
  
  uint8_t nums[1] = {4}; // 4 buttons per group
  
  timeStart = micros();
  myTFT.TotalRadioButtons(nums,1);
  timeCollect[0] = micros() - timeStart;
  timeStart = micros();
  
  myTFT.TotalRadioCircleButtons(nums,1);
  timeCollect[1] = micros() - timeStart;
  timeStart = micros();
  
  myTFT.SetAll_RB_Outer_Color(BLACK);
  myTFT.SetAll_RB_Toggled_Color(GREEN);
  myTFT.SetAll_RB_Untoggled_Color(YELLOW);
  timeCollect[2] = micros() - timeStart;
  timeStart = micros();
  
  myTFT.SetAll_RCB_Outer_Color(PURPLE); 
  myTFT.SetAll_RCB_Toggled_Color(BLUE);
  myTFT.SetAll_RCB_Untoggled_Color(RED);
  timeCollect[3] = micros() - timeStart;
}

void getButton()
{
  timeStart = micros();
  myTFT.RadioButton(10,10,50,50,0,0);
  timeCollect[4] = micros() - timeStart;
  myTFT.RadioButton(10,60,50,100,1,0 );
  myTFT.RadioButton(10,110,50,150,2,0 );
  myTFT.RadioButton(10,160,50,200,3,0 );
  timeCollect[5] = micros() - timeStart;
//================================================= 
  timeStart = micros();
  myTFT.RadioCircleButton(80,30,20,0,0 );
  timeCollect[6] = micros() - timeStart;
  myTFT.RadioCircleButton(80,80,20,1,0 );
  myTFT.RadioCircleButton(80,130,20,2,0 );
  myTFT.RadioCircleButton(80,180,20,3,0 );
  timeCollect[7] = micros() - timeStart;
}

Output: Time in milliseconds

Setup TRB: 0.003
Setup TRCB: 0.007
Set RB colors: 0.027
Set RCB colors: 0.031
1x RadioButton: 66.895
4x RadioButton: 267.587
1x RadioCircleButton: 451.563
4x RadioCircleButton: 1806.251
Total Time: 2589.999

Both types of latching buttons.

#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <TFT_Extension_old.h>
#include <math.h>
// Declare which fonts we will be using
extern uint8_t SmallFont[];

//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);
TFT_Extension_old myTFT(&myGLCD, &myTouch, LANDSCAPE);

unsigned long timeStart, timeCollect[9];
char * functs[11] = {
  "Set TC color: ", "Setup LC color: ", "Set TB color: ", "Set LB color: ","TC_Draw: ",
  "LC_Draw: ","TB_Draw: ","LB_Draw: ", "Total Time: "};

boolean last = LOW, latch = false;

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

void loop() {}

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();
  myGLCD.print("Latches", CENTER, 50);
  myGLCD.print("Buttons", CENTER, 170);
  
  timeStart = micros();
  myTFT.SetTouchCircleColors(0, ORANGE, PURPLE, FILL);        // ID number, Pressed Color, Released Color, FILL/NOFILL)
  timeCollect[0] = micros() - timeStart;
  timeStart = micros();
  myTFT.SetLatchCircleColors(1, WHITE, CYAN, FILL);          // ID number, Latched Color, UnLatched Color, FILL/NOFILL)
  timeCollect[1] = micros() - timeStart;
  timeStart = micros();
  myTFT.SetTouchButtonColors(0, GREEN, RED, FILL, ROUNDED);   // ID number, Pressed Color, Released Color, FILL/NOFILL,ROUNDED/NOTROUNDED)
  timeCollect[2] = micros() - timeStart;
  timeStart = micros();
  myTFT.SetLatchButtonColors(1, BLUE, YELLOW, FILL, ROUNDED); // ID number, Latched Color, UnLatched Color, FILL/NOFILL, ROUNDED/NOTROUNDED)
  timeCollect[3] = micros() - timeStart;
  getButton();
  myGLCD.clrScr();
  for(byte idx = 0; idx < 9; idx++)
  {
   myGLCD.print(functs[idx], 0, idx * 20);
   myGLCD.printNumF(float(timeCollect[idx]) / 1000.00,3, 200, idx * 20 );
  }  
}

void getButton()
{
  timeStart = micros();
  myTFT.TouchCircle_Draw(55,180,50,0); // (x,y,radius, ID number)
  timeCollect[4] = micros() - timeStart;
  timeStart = micros();
  myTFT.LatchCircle_Draw(265,55,50,1); // (x,y,radius, ID number)
  timeCollect[5] = micros() - timeStart;
  timeStart = micros();
  myTFT.TouchButton_Draw(220,135,310,225,0);// (x1,y1,x2,y2, ID number)
  timeCollect[6] = micros() - timeStart;
  timeStart = micros();
  myTFT.LatchButton_Draw(10,10,100,100,1);// (x1,y1,x2,y2, ID number)
  timeCollect[7] = micros() - timeStart;
  timeCollect[8] = micros() - timeCollect[0];
}

Output time in milliseconds

Set TC color: 0.011
Setup LC color: 0.007
Set TB color: 0.011
Set LB color: 0.011
TC_Draw: 1795.851
LC_Draw: 1795.851
TB_Draw: 167.507
LB_Draw: 167.515
Total Time: 3923.999

Both types of triangles:

#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <TFT_Extension_old.h>
#include <math.h>
// Declare which fonts we will be using
extern uint8_t SmallFont[];

//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);
TFT_Extension_old myTFT(&myGLCD, &myTouch, LANDSCAPE);

unsigned long timeStart, timeCollect[5];
char * functs[11] = {
  "Set TT color: ", "Setup LT color: ", "TT_Draw: ",
  "LT_Draw: ", "Total Time: "};

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

void loop() {}

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();
  myGLCD.print("Latches", CENTER, 50);
  myGLCD.print("Buttons", CENTER, 170);
  
  timeStart = micros();
  myTFT.SetTouchTriangleColors(0, ORANGE, PURPLE, FILL);        // ID number, Pressed Color, Released Color, FILL/NOFILL)
  timeCollect[0] = micros() - timeStart;
  timeStart = micros();
  myTFT.SetLatchTriangleColors(1, WHITE, CYAN, FILL);          // ID number, Latched Color, UnLatched Color, FILL/NOFILL)
  timeCollect[1] = micros() - timeStart;
  getButton();
  myGLCD.clrScr();
  for(byte idx = 0; idx < 5; idx++)
  {
   myGLCD.print(functs[idx], 0, idx * 20);
   myGLCD.printNumF(float(timeCollect[idx]) / 1000.00,3, 200, idx * 20 );
  }  
}

void getButton()
{
  timeStart = micros();
  myTFT.TouchTriangle_Draw(55,180,50,up, 0, 0); // (x,y,radius, ID number)
  timeCollect[2] = micros() - timeStart;
  timeStart = micros();
  myTFT.LatchTriangle_Draw(265,55,50,up, 0, 1); // (x,y,radius, ID number)
  timeCollect[3] = micros() - timeStart;
  timeCollect[4] = micros() - timeCollect[0];
}

Output:

Set TT color: 0.007
Set LT color: 0.011
TT_Draw: 419.235
LT_Draw: 417.835
Total Time: 838.088?

Here are the times for the radio button color functions.

#include <ITDB02_Graph16.h>
#include <ITDB02_Touch.h>
#include <TFT_Extension_old.h>
#include <math.h>
// Declare which fonts we will be using
extern uint8_t SmallFont[];

//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);
TFT_Extension_old myTFT(&myGLCD, &myTouch, LANDSCAPE);

unsigned long timeStart, timeCollect[13]; 
char * functs[13] = {
  "Set RBO color: ", "Set RCBO color: ", "Set RBT color: ", "Set RCBT color: ",
  "Set RBUT color: ", "Set RCBUT color: ", "Set RBO_BG color: ", "Set RCBO_BG color: ", 
  "Set RBT_BG color: ","Set RCBT_BG color: ", "Set RBUT_BG color: ","Set RCBUT_BG color: ", 
  "Total Time: "};
void setup()
{
  myGLCD.InitLCD(LANDSCAPE);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_LOW);
  Serial1.begin(115200);
  startup();
}

void loop() {
}

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();
  myGLCD.print("Latches", CENTER, 50);
  myGLCD.print("Buttons", CENTER, 170);

  timeStart = micros();
  myTFT.RB_Outer_Color(0,1,WHITE);
  timeCollect[0] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RCB_Outer_Color(0,1,WHITE);
  timeCollect[1] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RB_Toggled_Color(0,1,WHITE);
  timeCollect[2] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RCB_Toggled_Color(0,1,WHITE);
  timeCollect[3] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RB_Untoggled_Color(0,1,WHITE);
  timeCollect[4] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RCB_Untoggled_Color(0,1,WHITE);
  timeCollect[5] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RB_Outer_Color_By_Group(1, GREEN);
  timeCollect[6] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RCB_Outer_Color_By_Group(1, GREEN);
  timeCollect[7] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RB_Toggled_Color_By_Group(1, GREEN);
  timeCollect[8] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RCB_Toggled_Color_By_Group(1, GREEN);
  timeCollect[9] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RB_Untoggled_Color_By_Group(1, GREEN);
  timeCollect[10] = micros() - timeStart;
  
  timeStart = micros();
  myTFT.RCB_Untoggled_Color_By_Group(1, GREEN);
  timeCollect[11] = micros() - timeStart;
  timeCollect[12] = micros() - timeCollect[0];
  myGLCD.clrScr();
  for(byte idx = 0; idx < 13; idx++)
  {
    myGLCD.print(functs[idx], 0, idx * 16);
    myGLCD.printNumF((float(timeCollect[idx]) / 1000.00),6, 200, idx * 16 );
  }  
}

Output:

Set RBO color: .00799
Set RCBO color: 0.00799
Set RBT color: 0.00799
Set RCBT color: 0.00799
Set RBUT color: 0.00799
Set RCBUT color: 0.00799
Set RBO_BG color: 0.00399
Set RCBO_BG color: 0.00799
Set RBT_BG color: 0.00399
Set RCBT_BG color: 0.00399
Set RBUT_BG color: 0.00799
Set RCBUT_BG color: 0.00399
Total Time: 0.07988

Small update, I changed TouchDelay to TouchDelayButton and added two new functions, TouchDelayCircle and TouchDelayTriangle.

I’m still working on the TextButton function, I am able to display text in the center with no problem, but I am trying to make the button be able to rotate (Still no problem). However, getting the text to rotate and still stay centered is proving to be a bit more challenging then expected. I will hopefully get that function working soon.

EDIT: There was a slight hiccup with the Portrait vs Landscape modes. Its fixed now.

TFT_Extension.zip (37.7 KB)

UPDATE:
Both types of radio buttons now are able to have text in the center of them. Please note that the text will NOT be cutoff or the buttons size will NOT be altered if the text is larger than the button.
Newest version as of 4/11/2014

I am open to new function ideas if anyone has any. I will of course add your name or username to the functions description.

I am currently working on a star function and I should be done with it soon. As well as a polygon function which will allow the user to enter a number 3 - 10, and it will make the shape with the given sides. Filled in color may be difficult so for now it will just be unfilled.

Added: I finished both of them. They will be in the next update.

TFT_Extension.zip (38.4 KB)