I'm quite new to the topic of micro controllers and the Arduino and have done some simple circuits on a breadboard and a "build it straight from a guide" music-box (the tonuino) until now.
I now wanted to delve deeper into the subject and got myself a TFT touch display for my Mega 2560, a Nema 17 Stepper+Shield and some extra parts to build a motor control system for my camera slider (based on ->this guide).
The described project uses a 3.2" Display from Sainsmart that seems to be out of stock everywhere. So I had to to replace the screen with another one. My Progress so far:
The Search for the right screen
I started by buying a 3.2" screen and was at that moment already overwhelmed by how I should connect it to the Arduino. So i researched and found the advice to simply attach a TFT shield to the Mega that would save myself from all the cable clutter. The shield fitted perfect to the Mega, but the screen didn't fit to the shield.
At this point I asked for help on the Arduino Discord server and got the information that there are SPI Displays (which I had bought) and parallel displays (suitable for my shield) and that my combination won't fit together. So I've returned the SPI Display and bought a -> parallel screen with an included shield
Getting an Image
Initially the new screen didn't show anything either with sketches I found online. But then I found a posting here that made it clear that the answer where in the libraries I've used - UTFT and UTOUCH don't seem to work with my display (but they should according to the amazon page). I don't know exactly why - is it the ILI9486 IC or the size of 3.5" compared to the 3.2" in the example? Nevertheless, I switched to Adafruit GFX and MCU Friend and got it to show an image.
Getting Touchy
The next step was to get the touch function to work. I'Ve tried various approaches without any luck until I found a calibration sketch in the examples of the MCUFRIEND_kbv library. I've included parts of that sketch into my demo project and got the touch functionality to run for the whole screen as one big responsive zone.
Here start the problems
After defining the whole screen as touch zone I tried to narrow the zone down with another code snippet I found.
bool touchedWithin(TSPoint touch, unsigned x, unsigned y, unsigned w, unsigned h)
{
return (touch.x > x) && (touch.x < (w)) && (touch.y > y) && (touch.y < (h));
}
if(touchedWithin(p, 0, 0, 250, 250))
{Serial.println("Touch!");}
This works on an area in the upper right corner of the screen (more or less the red area). But I have no idea how the width and height of this area correlates with the size of the screen. Any value under roughly 200 in both w and h attributes doesn't produce any touchable area. Values around 250 create an area at the size of the red area. But if i make the button bigger, It goes haywire. I've tried to double and triple it in size from 50/50 to 100/100 and 150/150 with the correlating dimensions of the touchedWithin call to 250/250, 500/500 and 750/750. With those larger values the responding zone covers the whole screen again. My goal would be to create clickable buttons that are limited to the area their drawn counterparts show. Also, the "working" touch event with 0,0,250,250 creates a lot of responses in the monitor, not just a single "I've been clicked". As I want to control a motor shield later on, that shouldn't be a dozen or more responses... What am I missing, what am I doing wrong?
I'm using an original Arduino Mega 2560 R3 with a 3.5" TFT Display 480x320. The product page on Amazon even says the display is compatible with UTFT / UTFT_Buttons / Utouch Library, but all I get is a blank white screen when using those libraries. It seems I'm not the only ohne with this problem: shields - 3.5" TFT LCD Display is not working with Arduino Mega 2560 R3 - Arduino Stack Exchange
But the modified UTFT library didn't work either. I'd prefer UTFT over MCUFRIEND because the guide I'm following uses those libraries too.
Here's my current sketch with MCUFRIEND/Adafruit GFX:
// Start of "Borrowed" Setup from Adafruit TouchScreen Calibration Sketch
// TouchScreen_Calibr_native for MCUFRIEND UNO Display Shields
// adapted by David Prentice
// for Adafruit's <TouchScreen.h> Resistive Touch Screen Library
// from Henning Karlsen's original UTouch_Calibration program.
// Many Thanks.
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#define PORTRAIT 1
#define LANDSCAPE 0
#define USE_XPT2046 0
#define USE_LOCAL_KBV 1
#define PRESSURE_THRESHOLD 10
#define TOUCH_ORIENTATION PORTRAIT
#if defined(USB_PID) && USB_PID == 0x804E // Arduino M0 Native
#define Serial SerialUSB
#endif
// MCUFRIEND UNO shield shares pins with the TFT.
#if defined(ESP32)
int XP = 27, YP = 4, XM = 15, YM = 14; //most common configuration
#else
//int XP = 6, YP = A1, XM = A2, YM = 7; //most common configuration
int XP = 7, YP = A2, XM = A1, YM = 6; //next common configuration
//int XP=PB7,XM=PA6,YP=PA7,YM=PB6; //BLUEPILL must have Analog for YP, XM
#endif
#if USE_LOCAL_KBV
#include "TouchScreen_kbv.h" //my hacked version
#define TouchScreen TouchScreen_kbv
#define TSPoint TSPoint_kbv
#else
#include <TouchScreen.h> //Adafruit Library
#endif
TouchScreen ts(XP, YP, XM, YM, 300); //re-initialised after diagnose
TSPoint tp;
void readResistiveTouch(void)
{
tp = ts.getPoint();
pinMode(YP, OUTPUT); //restore shared pins
pinMode(XM, OUTPUT);
//digitalWrite(YP, HIGH); //because TFT control pins
//digitalWrite(XM, HIGH);
// Serial.println("tp.x=" + String(tp.x) + ", tp.y=" + String(tp.y) + ", tp.z =" + String(tp.z));
}
uint16_t readID(void) {
uint16_t ID = tft.readID();
if (ID == 0xD3D3) ID = 0x9486;
return ID;
}
#define TFT_BEGIN() tft.begin(ID)
bool ISPRESSED(void)
{
// .kbv this was too sensitive !!
// now touch has to be stable for 50ms
int count = 0;
bool state, oldstate;
while (count < 10) {
readResistiveTouch();
state = tp.z > 200; //ADJUST THIS VALUE TO SUIT YOUR SCREEN e.g. 20 ... 250
if (state == oldstate) count++;
else count = 0;
oldstate = state;
delay(5);
}
return oldstate;
}
// End of TS Calibration
#define BLACK 0x0000
#define NAVY 0x000F
#define DARKGREEN 0x03E0
#define DARKCYAN 0x03EF
#define MAROON 0x7800
#define PURPLE 0x780F
#define OLIVE 0x7BE0
#define LIGHTGREY 0xC618
#define DARKGREY 0x7BEF
#define BLUE 0x001F
#define GREEN 0x07E0
#define CYAN 0x07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define PINK 0xF81F
bool touchedWithin(TSPoint touch, unsigned x, unsigned y, unsigned w, unsigned h);
void setup() {
//Initializing TFT display:
tft.begin(tft.readID());
Serial.begin(9600);
Serial.print("TFT LCD Screen ID: ");
Serial.println(tft.readID());
//The resolution of the TFT screen can be determined using the following code.
Serial.print("TFT LCD Screen Width: ");
Serial.println(tft.width());
Serial.print("TFT LCD Screen Height: ");
Serial.println(tft.height());
// Fill TFT Screen with a color:
tft.fillScreen(LIGHTGREY);
delay(500);
//vertial grid
for(int drawHelper = 0;drawHelper<480;drawHelper+=10){
tft.drawLine(0, drawHelper, 320, drawHelper, DARKGREY);
}
//horizontal grid
for(int drawHelper = 0;drawHelper<320;drawHelper+=10){
tft.drawLine(drawHelper, 0, drawHelper, 480, DARKGREY);
}
delay(1000);
tft.drawRoundRect(50, 50, 215, 380, 10, BLACK);
delay(200);
tft.fillRoundRect(50, 50, 215, 380, 10, ORANGE);
tft.drawRoundRect(0, 0, 50, 50, 10, BLACK);
delay(200);
tft.fillRoundRect(0, 0, 50, 50, 10, MAROON);
delay(2000);
tft.setRotation(3);
tft.setCursor(90, 130);
tft.setTextColor(BLUE);
tft.setTextSize(4);
tft.setTextWrap(true);
tft.print("CLICK ON RED!");
tft.setRotation(0); // Reset Rotation
}
void loop() {
TSPoint p = ts.getPoint();
// NOTE: The touchscreen controller does NOT use the
// screen coordinates! It uses its own coordinate system
if(touchedWithin(p, 0, 0, 240, 240))
{Serial.println("Touch!");}
}
bool touchedWithin(TSPoint touch, unsigned x, unsigned y, unsigned w, unsigned h)
{
return (touch.x > x) && (touch.x < (w)) && (touch.y > y) && (touch.y < (h));
}
And this is the output of LCD_ID_readreg:
reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
reg(0x00C0) 00 0E 0E 0E 0E 0E 0E 0E 0E Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
reg(0x00CC) 00 04 Panel Control
reg(0x00D0) 00 00 00 Power Control
reg(0x00D2) 00 00 00 00 00 NVM Read
reg(0x00D3) 00 00 94 86 ILI9341, ILI9488
reg(0x00D4) 00 00 00 00 Novatek ID
reg(0x00DA) 00 54 RDID1
reg(0x00DB) 00 80 RDID2
reg(0x00DC) 00 66 RDID3
reg(0x00E0) 00 06 04 1E 06 1F 00 37 5F 6F 0B 17 04 39 36 0E GAMMA-P
reg(0x00E1) 00 0A 01 35 03 1E 09 4E 79 3E 07 16 0B 04 0E 0E GAMMA-N
reg(0x00EF) 00 80 00 10 60 40 ILI9327
reg(0x00F2) 00 18 A3 12 02 B2 12 FF 10 00 00 00 Adjust Control 2
reg(0x00F6) 00 54 80 66 Interface Control