Hallo,
folgende Situation: Mit einem ESP32 möchte ich unter anderem folgenden Touchscreen steuern: 2.8 TFT LCD with Touchscreen Breakout Board w/MicroSD Socket [ILI9341] : ID 1770 : $29.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Bei dem Display kann man zwischen SPI und 8Bit-parallel-Interface wählen. Ich hab mich für SPI-entschieden, obwohl es langsamer ist, da mir es einfach unkomplizierter erschien.
Das ganze dabei mit der von Adafruit bereitgestellten Bibliothek. Da diese jedoch für den Arduino ausgelegt ist, habe ich im Code(siehe weiter unten) bereits einige Anpassungen gemacht. Um die Funktionalität zu prüfen, wollte ich zu aller erst den Sketch breakouttouchpaint.ino ausprobiert. Fazit: Das Display funktioniert, der Touch gewissermaßen auch, jedoch völlig falsch kalibriert. Um es so auszudrücken: Im unteren Linken Bereich reagiert das Display auf Berührungen und "zeichnet" diese dann jedoch an einer komplett anderen Stelle...
Das ist der von mir angepasste Code, Verkabelung kann man daran ebenfalls ablesen.
/***************************************************
This is our touchscreen painting example for the Adafruit ILI9341 Breakout
----> http://www.adafruit.com/products/1770
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate, 4 or 5 pins are required to
interface (RST is optional)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
/** NOT FOR USE WITH THE TOUCH SHIELD, ONLY FOR THE BREAKOUT! **/
#include <Adafruit_GFX.h> // Core graphics library
#include <SPI.h>
#include <Adafruit_ILI9341.h>
#include "TouchScreen.h"
// These are the four touchscreen analog pins
#define YP 33 // must be an analog pin, use "An" notation!
#define XM 32 // must be an analog pin, use "An" notation!
#define YM 22 // can be any digital pin
#define XP 21 // can be any digital pin
// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
#define MINPRESSURE 10
#define MAXPRESSURE 1000
#define TFT_RST 4
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 15
#define TFT_DC 16
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC,TFT_RST);
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 325);
// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
void setup(void) {
// while (!Serial); // used for leonardo debugging
Serial.begin(115200);
Serial.println(F("Touch Paint!"));
tft.begin();
tft.setRotation(0);
tft.fillScreen(ILI9341_BLACK);
// make the color selection boxes
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
// select the current color 'red'
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
currentcolor = ILI9341_RED;
}
void loop()
{
// Retrieve a point
TSPoint p = ts.getPoint();
pinMode(XM, INPUT);
pinMode(XP, OUTPUT);
pinMode(YM, OUTPUT);
pinMode(YP, INPUT);
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y); /*
Serial.print("\tPressure = "); Serial.println(p.z);
*/
// we have some minimum pressure we consider 'valid'
// pressure of 0 means no pressing!
if (p.z < MINPRESSURE || p.z > MAXPRESSURE) {
return;
}
// Scale from ~0->1000 to tft.width using the calibration #'s
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
Serial.print(tft.height());
Serial.println(tft.width());
/*
Serial.print("("); Serial.print(p.x);
Serial.print(", "); Serial.print(p.y);
Serial.println(")");
*/
if (p.y < BOXSIZE) {
oldcolor = currentcolor;
if (p.x < BOXSIZE) {
currentcolor = ILI9341_RED;
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*2) {
currentcolor = ILI9341_YELLOW;
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*3) {
currentcolor = ILI9341_GREEN;
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*4) {
currentcolor = ILI9341_CYAN;
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*5) {
currentcolor = ILI9341_BLUE;
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
} else if (p.x < BOXSIZE*6) {
currentcolor = ILI9341_MAGENTA;
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
}
if (oldcolor != currentcolor) {
if (oldcolor == ILI9341_RED)
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
if (oldcolor == ILI9341_YELLOW)
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
if (oldcolor == ILI9341_GREEN)
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
if (oldcolor == ILI9341_CYAN)
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
if (oldcolor == ILI9341_BLUE)
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
if (oldcolor == ILI9341_MAGENTA)
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
}
}
if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
}
}
Ich gehe davon aus, dass es an diesen Zeilen liegt, durch die werden ja die Ecken des Displays definiert. Die sind übrigens standardmäßig so.
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
Gibt es hier eine "bessere" Alternative als zufällig mit den Werten herumzuspielen und darauf zu hoffen, dass die Kalibrierung irgendwann passt? Oder liegt das Problem wo anders und es geht vielleicht sogar einfacher?
Ich bedanke mich schonmal im Voraus an jeden, der versucht zu helfen...