[Suche Hilfe]Buttons für TFT mit kapazitivem Touch (SSD1963 ivm FT5206)

Es gibt nur 1 Methode, die angepaßt werden muß: checkButtons().

Darin muß abgefragt werden, welche Position auf dem Display gedrückt wurde, und damit die Liste der definierten Buttons abgefragt werden.

Dafür sollte reichen, in int UTFT_Buttons::checkButtons() die Abfrage der Koordinaten von _URTouch->read() usw. auf die Methode der anderen Touch-Bibliothek zu ändern. Alles übrige dient der Darstellung der Buttons, muß also nicht geändert werden.

Hallo zusammen.

Also, dank des Denkanstoßes von Tommy habe ich es geschafft einen von mir gewünschten Punkt auf dem Bildschirm nach betätigen dazu zu bringen eine Reaktion zu zeigen.

Ich habe also ein einfaches Rechteck mit 40 Pixeln Kantenlänge gezeichnet, dieses mit Blau ausgefüllt und einen vielversprechendem Namen (Test) versehen.

Anhand der Daten durch das drawRect habe ich gemäß Tommy´s Hinweis die Abfrage genau auf die Pixel begrenzt und lasse bei einem "Treffer" einen weißen Kreis zeichnen.

if(touchLocations[i].x>=120&&touchLocations[i].x<=160&&touchLocations[i].y>=160&&touchLocations[i].y<=200 )myGLCD.setColor(255, 255, 255),myGLCD.fillCircle(300,200, 20 );

Soweit so gut. Das hilft mir sehr weiter und ich kann damit das gewünschte Ergebnis erzielen.
Allerdings ist diese Verfahrensweise für mein Projekt sehr aufwendig und eigentlich gibt es ja speziell dafür eine Bibliothek (UTFT_Buttons), welche das Ganze vereinfachen soll.

Weiterhin habe ich mir den Hinweis von DrDiettrich angesehen, kann aber nicht nachvollziehen wie du das meinst.

Bitte berichtige mich wenn ich etwas falsch interpretiere, wie du weißt fehlt mir da offensichtlich die ebenenspezifische Sichtweise. :frowning:
Ich will es aber zumindest versuchen zu verstehen und, selbst wenn es nicht klappt, zumindest etwas dazugelernt haben.

Die URTouch.h nutzt vermutlich folgenden Code zum Auslesen der Koordinaten, oder?

class URTouch
{
	public:
		int16_t	TP_X ,TP_Y;

				URTouch(byte tclk, byte tcs, byte tdin, byte dout, byte irq);

		void	InitTouch(byte orientation = LANDSCAPE);
		void	read();
		bool	dataAvailable();
		int16_t	getX();
		int16_t	getY();
		void	setPrecision(byte precision);

		void	calibrateRead();

Aber in den Programmzeilen ist ja hinterlegt, dass er für den URTouch die Pins zur Kommunikation braucht (touchClock, touchChipselect, touchDataIn,touchDataout, touchIrq)

Wie bringe ich der Bibliothek bei, dass sie die Daten aus der CTP IIC Adresse 0x38 beziehen muss?

Ich hoffe ihr habt noch ein wenig Geduld mit mir.

Wie immer danke ich für eure aufgebrachte Zeit meinen Schwachsinn zu lesen.

LG Chris

Schön, dass es bis hierher funktioniert hat.
Jetzt hast Du 2 mögliche Wege:

Du schreibst Dir einen Ersatz für die UTFT_Button auf dieser Basis selbst oder Du baust die vorhandene UTFT_Button um, wie DrDiettrich schon vorgeschlagen hatte.

Ich halte die 2. Variante für die schneller realisierbare, bei der ersten lernst Du allerdings mehr.
Ich weiß jetzt nicht, wie Deine Lib die "getuchte" X/Y-Position ermittelt aber genau an dem Punkt kannst Du ansetzen. In der UTFT_Button.cpp gibt es die Methode:

int UTFT_Buttons::checkButtons()
{
    if (_URTouch->dataAvailable() == true)   // ist was da?
    {
		_URTouch->read();  // hole die Koordinaten
		int		result = -1;
		int		touch_x = _URTouch->getX();  // getuchter X-Wert
		int		touch_y = _URTouch->getY();  // getuchter Y-Wert
		word	_current_color = _UTFT->getColor();
  
		for (int i=0;i<MAX_BUTTONS;i++)
		{
			if (((buttons[i].flags & BUTTON_UNUSED) == 0) and ((buttons[i].flags & BUTTON_DISABLED) == 0) and (result == -1))
			{
				if ((touch_x >= buttons[i].pos_x) and (touch_x <= (buttons[i].pos_x + buttons[i].width)) and (touch_y >= buttons[i].pos_y) and (touch_y <= (buttons[i].pos_y + buttons[i].height)))
					result = i;
			}
		}
		if (result != -1)
		{
			if (!(buttons[result].flags & BUTTON_NO_BORDER))
			{
				_UTFT->setColor(_color_hilite);
				if (buttons[result].flags & BUTTON_BITMAP)
					_UTFT->drawRect(buttons[result].pos_x, buttons[result].pos_y, buttons[result].pos_x+buttons[result].width, buttons[result].pos_y+buttons[result].height);
				else
					_UTFT->drawRoundRect(buttons[result].pos_x, buttons[result].pos_y, buttons[result].pos_x+buttons[result].width, buttons[result].pos_y+buttons[result].height);
			}
		}

		while (_URTouch->dataAvailable() == true) {};

		if (result != -1)
		{
			if (!(buttons[result].flags & BUTTON_NO_BORDER))
			{
				_UTFT->setColor(_color_border);
				if (buttons[result].flags & BUTTON_BITMAP)
					_UTFT->drawRect(buttons[result].pos_x, buttons[result].pos_y, buttons[result].pos_x+buttons[result].width, buttons[result].pos_y+buttons[result].height);
				else
					_UTFT->drawRoundRect(buttons[result].pos_x, buttons[result].pos_y, buttons[result].pos_x+buttons[result].width, buttons[result].pos_y+buttons[result].height);
			}
		}

		_UTFT->setColor(_current_color);
		return result;
	}
	else
		return -1;
}

Ich habe mal die Zeilen kommentiert, die Du (vereinfacht ausgedrückt) ersetzen musst. Es ist noch etwas mehr zu ändern, da die Typen der Touch-Klasse nicht passt, aber in die Richtung geht es.

Gruß Tommy

Hey Tommy,

nachdem die Schäden durch Sturm Friederike beseitigt sind, habe ich mich mal versucht den Ablauf durch deine Erklärungen zu verstehen. Wenn ich einen Denkfehler habe, so berichtige mich.

Gemäß deinem Codeauschnitt fragt er ja als erstes ab, sind aus der Bibliothek URTouch Daten vorhanden. Die UTFT, die UTFT_Button und URTouch mit der URTouchCD sind irgendwie alle miteinander verwoben, keine kann ohne die Andere.

Ich habe mir die Codesegmente angesehen (ohne den größten Teil davon genau zu verstehen), aber ich denke der "Ursprung der Initialisierung und Abfrage der x und y Koordinaten erfolgt in der URTouch.

Hier mal der Code der URTouch.cpp

/
 

#include "URTouch.h"
#include "URTouchCD.h"

#if defined(__AVR__)
 #include "hardware/avr/HW_AVR.inc"
#elif defined(__PIC32MX__)
 #include "hardware/pic32/HW_PIC32.inc"
#elif defined(__arm__)
 #include "hardware/arm/HW_ARM.inc"
#endif

URTouch::URTouch(byte tclk, byte tcs, byte din, byte dout, byte irq)
{
 T_CLK = tclk;
 T_CS = tcs;
 T_DIN = din;
 T_DOUT = dout;
 T_IRQ = irq;
}

void URTouch::InitTouch(byte orientation)
{
 orient = orientation;
 _default_orientation = CAL_S>>31;
 touch_x_left = (CAL_X>>14) & 0x3FFF;
 touch_x_right = CAL_X & 0x3FFF;
 touch_y_top = (CAL_Y>>14) & 0x3FFF;
 touch_y_bottom = CAL_Y & 0x3FFF;
 disp_x_size = (CAL_S>>12) & 0x0FFF;
 disp_y_size = CAL_S & 0x0FFF;
 prec = 10;

 P_CLK = portOutputRegister(digitalPinToPort(T_CLK));
 B_CLK = digitalPinToBitMask(T_CLK);
 P_CS = portOutputRegister(digitalPinToPort(T_CS));
 B_CS = digitalPinToBitMask(T_CS);
 P_DIN = portOutputRegister(digitalPinToPort(T_DIN));
 B_DIN = digitalPinToBitMask(T_DIN);
 P_DOUT = portInputRegister(digitalPinToPort(T_DOUT));
 B_DOUT = digitalPinToBitMask(T_DOUT);
 P_IRQ = portInputRegister(digitalPinToPort(T_IRQ));
 B_IRQ = digitalPinToBitMask(T_IRQ);

 pinMode(T_CLK,  OUTPUT);
    pinMode(T_CS,   OUTPUT);
    pinMode(T_DIN,  OUTPUT);
    pinMode(T_DOUT, INPUT);
    pinMode(T_IRQ,  OUTPUT);

 sbi(P_CS, B_CS);
 sbi(P_CLK, B_CLK);
 sbi(P_DIN, B_DIN);
 sbi(P_IRQ, B_IRQ);
}

void URTouch::read()
{
 unsigned long tx=0, temp_x=0;
 unsigned long ty=0, temp_y=0;
 unsigned long minx=99999, maxx=0;
 unsigned long miny=99999, maxy=0;
 int datacount=0;

 cbi(P_CS, B_CS);                    

 pinMode(T_IRQ,  INPUT);
 for (int i=0; i<prec; i++)
 {
 if (!rbi(P_IRQ, B_IRQ))
 {
 touch_WriteData(0x90);        
 pulse_high(P_CLK, B_CLK);
 temp_x=touch_ReadData();

 if (!rbi(P_IRQ, B_IRQ))
 {
 touch_WriteData(0xD0);      
 pulse_high(P_CLK, B_CLK);
 temp_y=touch_ReadData();

 if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096))
 {
 tx+=temp_x;
 ty+=temp_y;
 if (prec>5)
 {
 if (temp_x<minx)
 minx=temp_x;
 if (temp_x>maxx)
 maxx=temp_x;
 if (temp_y<miny)
 miny=temp_y;
 if (temp_y>maxy)
 maxy=temp_y;
 }
 datacount++;
 }
 }
 }
 }
 pinMode(T_IRQ,  OUTPUT);

 if (prec>5)
 {
 tx = tx-(minx+maxx);
 ty = ty-(miny+maxy);
 datacount -= 2;
 }

 sbi(P_CS, B_CS);                    
 if ((datacount==(prec-2)) or (datacount==PREC_LOW))
 {
 if (orient == _default_orientation)
 {
 TP_X=ty/datacount;
 TP_Y=tx/datacount;
 }
 else
 {
 TP_X=tx/datacount;
 TP_Y=ty/datacount;
 }
 }
 else
 {
 TP_X=-1;
 TP_Y=-1;
 }
}

bool URTouch::dataAvailable()
{
 bool avail;
 pinMode(T_IRQ,  INPUT);
 avail = !(rbi(P_IRQ, B_IRQ));
 pinMode(T_IRQ,  OUTPUT);
 return avail;
}

int16_t URTouch::getX()
{
 long c;

 if ((TP_X==-1) or (TP_Y==-1))
 return -1;
 if (orient == _default_orientation)
 {
 c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
 if (c<0)
 c = 0;
 if (c>disp_x_size)
 c = disp_x_size;
 }
 else
 {
 if (_default_orientation == PORTRAIT)
 c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
 else
 c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
 if (c<0)
 c = 0;
 if (c>disp_y_size)
 c = disp_y_size;
 }
 return c;
}

int16_t URTouch::getY()
{
 int c;

 if ((TP_X==-1) or (TP_Y==-1))
 return -1;
 if (orient == _default_orientation)
 {
 c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
 if (c<0)
 c = 0;
 if (c>disp_y_size)
 c = disp_y_size;
 }
 else
 {
 if (_default_orientation == PORTRAIT)
 c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
 else
 c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
 if (c<0)
 c = 0;
 if (c>disp_x_size)
 c = disp_x_size;
 }
 return c;
}

void URTouch::setPrecision(byte precision)
{
 switch (precision)
 {
 case PREC_LOW:
 prec=1; // DO NOT CHANGE!
 break;
 case PREC_MEDIUM:
 prec=12; // Iterations + 2
 break;
 case PREC_HI:
 prec=27; // Iterations + 2
 break;
 case PREC_EXTREME:
 prec=102; // Iterations + 2
 break;
 default:
 prec=12; // Iterations + 2
 break;
 }
}

void URTouch::calibrateRead()
{
 unsigned long tx=0;
 unsigned long ty=0;

 cbi(P_CS, B_CS);                    

 touch_WriteData(0x90);        
 pulse_high(P_CLK, B_CLK);
 tx=touch_ReadData();

 touch_WriteData(0xD0);      
 pulse_high(P_CLK, B_CLK);
 ty=touch_ReadData();

 sbi(P_CS, B_CS);                    

 TP_X=ty;
 TP_Y=tx;
}

Dort scheint er auch die Daten der Calibrierung aus der URTouchCD zu holen. Dies scheint ja der Sketch zur Kalibrierung des TfT zu sein, oder?

Wenn also die Abfragen der Koordinaten in der URTouch dementsprechend geändert werden würden, dann müsste (theoretisch nach meinem Verständnis) neben der Kalibrierung (URTouchCD) auch die UTFT_Buttons funktionieren.

Du sagst, du weißt nicht genau wie "meine Lib" die Koordinaten ermittelt.

Das Beispiel zum Testen des Touch-Controllers beinhaltet die Abfrageroutinen wie folgt:

Datei befindet sich im Anhang... Mehr als 9000 Character

Ich habe das ganze Gedöns was die Standartdemos für TFT beinhaltet mal auskommentiert.
Ich vermute, dass grundlegende Problem (außer meiner Beschränktheit es gänzlich zu verstehen) ist, dass die Abfrage über den adressierten I²C Bus erfolgen muss und nicht wie im Sketch URTouch bzw UFTF über die Serial 4-Pin bzw 5-Pin Methode.

Sind meine Gedankengänge bis dahin richtig?

Vielen Dank fürs Lesen und die Zeit die ihr opfert um einen Unwissenden weiterzubilden.

LG Chris

EDIT: post zusammengeführt!

Capacitive_Touch_Test.ino (15.2 KB)

Deine Gedankengänge sind grundlegend richtig.
Der kapazitive Sketch ist auf Multitouch ausgelegt. Ich würde immer von nur 1 Touch ausgehen.

struct TouchLocation
{
  uint16_t x;
  uint16_t y;
};

TouchLocation touchLocations[1];  // Wir wollen nur einen Button gleichzeitig

....

// in checkButtons()
int		result = -1;
uint8_t count = readFT5206TouchLocation( touchLocations, 1);
if (count > 0) { // das sollte dem available entsprechen
  int touch_x = touchLocations[0].x;
  int touch_y = touchLocations[0].y;
....
}

Die ganzen Funktionen vom kapazitiven Touch mit rein kopieren oder in eine eigene Lib auslagern.
Alles völlig ungetestet, da ich die Hardware nicht habe.

Gruß Tommy

Hallo Tommy,

ich nehme an, du meinst mit // in checkButtons() die Veränderungen sollen in der UTFT_Buttons.cpp vorgenommen werden?

Wenn ja, dann bekomme ich bereits beim Kompilieren Fehler...

LG Chris

Du musst auch die Funktionen aus Deinem Testsketch da mit rein packen.

Gruß Tommy

Hmm,

danke für Zeit und die Mühe, aber ich bin offensichtlich raus. Es ist für mich nicht möglich, die Bibliotheken so umzuschreiben, dass es mit meiner Hardware passt.
Mir fehlt dazu das passende Know-How.

Dann werde ich das Projekt begraben und mir einfach einen LCD mit passenden Touch-Controller kaufen.

Jemand Interesse an einem 7"LCD mit kapazitivem Touchcontroller? Schutzfolie ist noch drauf :wink:

LG Chris

Wirf nicht gleich die Flinte ins Korn. Ich werde mal schauen, ob ichs blind zusammen gestellt bekomme.

Gruß Tommy

Hi

Ich befürchte, daß Du das LCD kaum so günstig verschicken kannst, wie's der Freundliche vom fernen Kontinent hinbekommt.
Wenn jetzt noch das Display selber nicht nur verschenkt werden soll ... so leid es mir tut - Das wirst Du, am Besten/Billigsten, behalten müssen.

MfG

Naja verschicken kostet 3,99€

Das LCD mit Touch kostet knappe 50€ aus Fernost, da ist doch eine gewisse Differenz. Ich hatte ja auch ein Zwinker-Smiley dahinter gemacht.

Zur Not wird es halt nur ein LCD ohne die Möglichkeit des Touchscreens. Wetterstation oder ähnliches.

Das ist lieb gemeint Tommy, es ist halt so, dass ich ein schlechtes Gewissen habe eure Zeit so zu verschwenden.
Und das nur weil ich zu doof bin, dass ganze zu kapieren.

Wie gesagt, mit den passenden Libs war es beim ersten nicht das Problem die Buttons und Funktionen anhand der Keywords in den Beschreibungen zu erstellen. Aber dann eine Bibliothek umzuschreiben ist dann doch eine ganz andere Hausnummer.

LG Chris

Sorry, so schnell geht das dann doch nicht, da ich keinerlei TFT-Libs installiert habe. Da muss ich zuviele Abhängigkeiten auflösen.
Da Du es schon zum Verkauf angeboten hast, will ich dann auch nicht erst mit einer Installationsorgie beginnen und lasse es.

Gruß Tommy

Tommy das mit dem Verkauf war ein Spaß!

Das war wie gesagt ein Zwinkersmiley.

Es sind wie gesagt folgende Libs

UTFT
UTFT_Buttons
URTouch

Mehr sind es nicht.

Vielen Dank Tommy

Ich habe mal was "schmutzig" zusammengeworfen. Es kompiliert aber der Linker findet setup und loop nicht.
Mehr Zeit möchte ich da jetzt nicht investieren. Evtl. hat jemand eine Idee, ich hänge es mal ran.

Die UTFT_Button habe ich in UTFT_CButton umbenannt, damit es sich nicht mit der Original-Lib beißt.
Die URTouch habe ich nicht rausoperiert, obwohl die nicht mehr gebraucht wird.

Gruß Tommy

UTFT_CButtons.zip (5.28 KB)

So, gerade von Arbeit gekommen. Ich werde es morgen testen und dir Feedback geben.
Danke dir erneut für deine Zeit und Mühe.

LG Chris

Hallo Tommy,

ich danke dir erneut für deine Mühe. Ja, es kompiliert und der Sketch wandert auch auf den Atmega. Allerdings haben die Buttons keine Funktion.
Eventuell hat ja jemand noch eine zündende Idee.

DrDiettrich hatte ja einen ähnlichen, wenn nicht sogar den gleichen Weg vorgeschlagen. Wenn er das liest schaut er vielleicht mal über deine Arbeit.

LG Chris

Schreibe Dir in die checkButtons Serial.println rein und schaue, was überhaupt als X/Y ankommt.
Evtl. fehlt auch eine Initialisierung aus Deinem Testsketch. Der war etwas wirr.

Das musst Du jetzt rausknobeln, weil nur Du die Hardware hast.

Gruß Tommy

Hey Tommy,

ja die Initialisierung fehlt. Habe ich auch nachgetragen. Allerdings wirft der Serielle Monitor nichts brauchbares aus. Genaugenommen einfach nur eine 0.

Danke dennoch für die Mühe.

LG Chris

Mit der UTFT hab ich auch mal gekämpft... erfolglos, obwohl ich sagen muss, dass die UTFT eigentlich sehr gut ist... Allerdings bin ich inzwischen bei sumotoy´s lib zum RA8875 gelandet- darum kann ich dir mit der UTFT in keinster Weise helfen.

Aber ich denke der händische Weg, den wir schon weiter oben gezeigt haben, ist doch nicht so kompliziert- oder?