2.4 TFT SPI using ILI9341 - Getting Touch Screen to Work with UNO - Please Help

Refer to attached image of my problem display featuring a Touch Screen with a UNO.

Having no problems displaying to screen (refer to #43 at this post of mine 2.4" touch screen display ili9341 - Displays - Arduino Forum ) On course I've converted I/O to 3.3V instead of 5V to make display work.

But how do you get the touch screen to work possibly using UTouch library . Does anyone have an example please .

Edit: the code works with mu DUE and I do get readings out of it.

I have the same screen you do, and I just tried this, but I think the touch screen pins also need to be converted to 3.3v and I don't have any CM4050 chips yet.

#include <UTouch.h>

UTouch  myTouch( 6, 5, 4, 3, 2);

void setup()
{
  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);
  Serial.begin(115200);
}

void loop()
{
    if (myTouch.dataAvailable())
    {
      myTouch.read();
      int x=myTouch.TP_X;
      int y=myTouch.TP_Y;
      Serial.print(x); Serial.print('\t'); Serial.println(y);
    }
}

HazardMind "your bloods worth bottling...." I'm now with your help actually getting some data off the touch screen showing on the Serial Monitor.

For other readers of this post your mention of UTouch myTouch( 6, 5, 4, 3, 2);
actually requires this display/touch screen wired to a UNO as follows:
T_CLK Uno pin D6
T_CS D5
T_DIN D4
T_DO D3
IRQ D2

This then allows the TFT screen to then be connected to UNO digital pins 9-13 as per my previous post.

The Arduino I'm using is actually a Freaduino which has a slide switch to select 5V / 3.3V for the outputs. I've just received some CD4050 hex buffers off ebay so later today I may try converting my test rig to a UNO or NANO to check my screen still displays with the 5V outputs converted down to 3.3V.

I sense I may be getting to the limit of what a UNO can do compared to your DUE which has a lot more horsepower. The author of the UTFT / UTouch libraries also makes no real mention of stand alone UNOs e.g. the code fragment below..... including mention of the following line which doesn't relate to our particular TFT Module UTFT myGLCD(ITDB32S,38,39,40,41);

// Initialize display
// ------------------
// Set the pins to the correct ones for your development board
// -----------------------------------------------------------
// Standard Arduino Uno/2009 Shield : ,19,18,17,16
// Standard Arduino Mega/Due shield : ,38,39,40,41
// CTE TFT LCD/SD Shield for Arduino Due : ,25,26,27,28
// Teensy 3.x TFT Test Board : ,23,22, 3, 4
// ElecHouse TFT LCD/SD Shield for Arduino Due : ,22,23,31,33
//
// Remember to change the model parameter to suit your display module!
UTFT myGLCD(ITDB32S,38,39,40,41);

My bottom line is I'd just like to be able to have some buttons on the screen that can be clicked on to cause certain program actions, the beginning of developing a GUI

Appreciate any more help / comments forthcoming

I got the screen to work with the Adafruit library. Adafruit_ILI9341

Try this calibration sketch, I have not tested it yet with this display.

#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_ILI9341.h>
#include <UTouch.h>

UTouch  myTouch( 6, 5, 4, 3, 2);

#define LANDSCAPE 1
#define PORTRAIT 0

// This is calibration data for the raw touch data to the screen coordinates
#define Orient LANDSCAPE
#define Width 320
#define Height 240

#define IsWithin(x, a, b) ((x>=a)&&(x<=b))
// My values from my other sketches
#define TS_MINX 142
#define TS_MINY 125
#define TS_MAXX 3871
#define TS_MAXY 3727

#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define Button_X 10
#define Button_Y 10
#define ButtonWidth 100
#define ButtonHeight 50

long _Height, _Width;

void setup(void)
{
  Serial.begin(115200);
  tft.begin();
  tft.fillScreen(ILI9341_BLUE);
  tft.setRotation(0);

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

  if (Orient == LANDSCAPE)
  {
    _Width = Width;
    _Height = Height;
  }
  else
  {
    _Width = Height;
    _Height = Width;
  }
  
  tft.fillRect(Button_X, Button_Y, ButtonWidth, ButtonHeight, 0xF800);
}

unsigned long MinX = 0xffff, MinY = 0xffff;
unsigned long MaxX = 0, MaxY = 0;
void loop()
{
  if (myTouch.dataAvailable())
  {
    myTouch.read();
    int tx = myTouch.TP_X;
    int ty = myTouch.TP_Y;

    MinX = min(MinX, tx);
    MaxX = max(MaxX, tx);

    MinY = min(MinY, ty);
    MaxY = max(MaxY, ty);
    
    Serial.println();
    Serial.print(MinX); Serial.print(F(" : ")); Serial.print(MaxX);
    Serial.print(F('\t'));
    Serial.print(MinY); Serial.print(F(" : ")); Serial.println(MaxY);
    Serial.print(F("CAL_X 0x")); Serial.print((MaxX << 14) | MinX);Serial.println(F("UL"));
    Serial.print(F("CAL_Y 0x")); Serial.print((MaxY << 14) | MinY);Serial.println(F("UL"));
    Serial.print(F("CAL_S 0x")); Serial.print((Orient & (1UL << 31)) | (Width << 14) | Height);Serial.println(F("UL"));
  }
  
  if(TouchButton(Button_X, Button_Y, ButtonWidth, ButtonHeight))
    tft.fillRect(Button_X, Button_Y, ButtonWidth, ButtonHeight, 0x0FF0);
  else 
    tft.fillRect(Button_X, Button_Y, ButtonWidth, ButtonHeight, 0xF800);
}


byte TouchButton(int x, int y, int w, int h)
{
  myTouch.read();
  int touchX = myTouch.TP_X;
  int touchY = myTouch.TP_Y;
  
  int X = map(touchX, TS_MINX, TS_MAXX, 0, _Width);
  int Y = map(touchY, TS_MINY, TS_MAXY, 0, _Height);
 
  return (IsWithin(X, x, x + w ) & IsWithin(Y, y, y + h));
}

Your additional code failed to compile for my UNO (Freaduino) due to your use of F when you pass flash-memory based strings e.g. Serial.print(F(“Hello World”))

This may work on a DUE but not in more basic Arduino.

Simple solution - I just deleted all of your F from your code & it runs OK and on Serial Monitor I'm seeing something like following:

2635 : 2689 2764 : 2824
CAL_X 0x44059211UL
CAL_Y 0x46271180UL
CAL_S 0x2147483889UL

I don't know yet specifically what it is saying with the code like " Serial.print(F("CAL_S 0x")); Serial.print((Orient | (1UL << 31)) | (Width << 14) | Height);Serial.println(F("UL"));

But the CAL_X and CAL_Y I assume is screen co-ordinates.

I've now printed out a hard copy of the UTouch & UTFT Manuals so I can try to see what is going on.

p.s. The new code also displays the button the screen.

Please continue to post me if possible.

You need to touch the screen in all four corners. Use a stylus for best results. Also only touch the corners that are over the display and not the black boarder.

I forgot to make these display as HEX values.

Below is the fixed version.

    Serial.print("CAL_X 0x"); Serial.print((MaxX << 14) | MinX, HEX); Serial.println("UL");
    Serial.print("CAL_Y 0x"); Serial.print((MaxY << 14) | MinY, HEX); Serial.println("UL");
    Serial.print("CAL_S 0x"); Serial.print((Orient & (1UL << 31)) | (Width << 14) | Height, HEX); Serial.println("UL");

Full fixed code

#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_ILI9341.h>
#include <UTouch.h>

UTouch  myTouch( 6, 5, 4, 3, 2);

#define LANDSCAPE 1
#define PORTRAIT 0

// This is calibration data for the raw touch data to the screen coordinates
#define Orient LANDSCAPE
#define Width 320
#define Height 240

#define IsWithin(x, a, b) ((x>=a)&&(x<=b))
// My values from my other sketches
#define TS_MINX 142
#define TS_MINY 125
#define TS_MAXX 3871
#define TS_MAXY 3727

#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define Button_X 10
#define Button_Y 10
#define ButtonWidth 50
#define ButtonHeight 50

long _Height, _Width;

void setup(void)
{
  Serial.begin(115200);
  tft.begin();
  tft.fillScreen(ILI9341_BLUE);
  tft.setRotation(0);

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

  if (Orient == LANDSCAPE)
  {
    _Width = Width;
    _Height = Height;
  }
  else
  {
    _Width = Height;
    _Height = Width;
  }
  
  tft.fillRect(Button_X, Button_Y, ButtonWidth, ButtonHeight, 0xF800);
}

unsigned long MinX = 0xffff, MinY = 0xffff;
unsigned long MaxX = 0, MaxY = 0;
void loop()
{
  if (myTouch.dataAvailable())
  {
    myTouch.read();
    int tx = myTouch.TP_X;
    int ty = myTouch.TP_Y;

    MinX = min(MinX, tx);
    MaxX = max(MaxX, tx);

    MinY = min(MinY, ty);
    MaxY = max(MaxY, ty);
    
    Serial.println();
    Serial.print(MinX); Serial.print(F(" : ")); Serial.print(MaxX);
    Serial.print(F('\t'));
    Serial.print(MinY); Serial.print(F(" : ")); Serial.println(MaxY);
    Serial.print(F("CAL_X 0x")); Serial.print(((MaxX << 14) & 0x3FFF) | (MinX & 0x3FFF), HEX);Serial.println(F("UL"));
    Serial.print(F("CAL_Y 0x")); Serial.print(((MaxY << 14) & 0x3FFF) | (MinY & 0x3FFF), HEX);Serial.println(F("UL"));
    Serial.print(F("CAL_S 0x")); Serial.print((Orient & (1UL << 31)) | ((Width << 12) & 0x0FFF) | (Height & 0x0FFF), HEX);Serial.println(F("UL"));
  }
  
  if(TouchButton(Button_X, Button_Y, ButtonWidth, ButtonHeight))
    tft.fillRect(Button_X, Button_Y, ButtonWidth, ButtonHeight, 0x0FF0);
  else 
    tft.fillRect(Button_X, Button_Y, ButtonWidth, ButtonHeight, 0xF800);
}


byte TouchButton(int x, int y, int w, int h)
{
  myTouch.read();
  int touchX = myTouch.TP_X;
  int touchY = myTouch.TP_Y;
  
  int X = map(touchX, TS_MINX, TS_MAXX, 0, _Width);
  int Y = map(touchY, TS_MINY, TS_MAXY, 0, _Height);
 
  return (IsWithin(X, x, x + w ) & IsWithin(Y, y, y + h));
}

Hi

I also have the 2.4 TFT SPI using ILI9341 "with touch" screen.

I can get the screen working with resistors and a cd4050. So the screen works, but not the touch part. Please can someone provide the connectivity part for touch.

Please help, kind regards
Dean

You need to provide 3.3V logic for the Touch controller too.

Either add the Touch controller to the proper hardware SPI bus.
Or bit-bash it with completely separate pins. e.g. with UTouch library.

David.