ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display)
Programmierung des Touchscreen Digitizer XPT2046

Bevor ihr mit diesem Artikel startet, solltet ihr euch zuerst ein wenig einlesen und die Hardware und das Pinout des TouchScreen-ESP32 kennenlernen. Gerade die dort erwähnten verwendeten GPIO-Pins des ESP32-2432S028 werden wir heute wieder brauchen.

Außerdem solltet ihr euch eine Entwicklungsumgebung mit PlatformIO einrichten, wie in diesem Artikel besprochen. Danach solltet ihr noch den Artikel Programmierung des Displays mit der TFT_eSPI-Library lesen, indem wir etwas auf dem Display ausgeben.

Das A und O des Cheap Yellow Display ist natürlich der Touchscreen, also dass man (fast) wie auf dem Smartphone Dinge anzeigen und auswählen kann. Das Darstellen von Inhalten auf dem Display haben wir das letzte mal gemacht. Heute geht es darum, die Taps - so heißen die Klicks auf einem Touchscreen - auszuwerten.

Der XPT2046 Digitizer

Im ESP32-2432S028R ist ein resistiver Touch-Digitizer vom Typ XPT2046 verbaut. Dafür steht auch das "R" am Ende. "Resistiv" heißt hier, er reagiert auf einen Widerstandswert, der durch Druck einer über das Display gespannten Folie auswerten kann, wenn diese an einer bestimmten Position niedergedrückt wird.

Der XPT2046 Digitizer kann die Position bis zu 125'000 mal die Sekunde (entsprechend 125 kHz Sampling Frequency) abfragen, kann mit 2.2 bis 3.6 Volt versorgt werden und wird über SPI angesprochen. Die entsprechenden GPIO-Pins findet ihr im Artikel Hardware. Er ist mit 260 µA sehr stromsparend.

Der XPT2046 in unserem Cheap Yellow Display liefert X und Y Werte zwischen 0 und 4095 (12 bit Auflösung), je nach Druckpunktort, die prinzipbedingt eine kleine Abweichung aufweisen können. Außerdem kann er in gewissem Maße den Druck messen, der beim Drücken ausgeübt wurde.

Ein resistiver Digitizer braucht immer ein gewisses Maß an Druck, damit er funktioniert. Darum bedient man ihn mit dem Fingernagel oder einem Stift. Ein solcher wird mitgeliefert; der hat allerdings nicht so die tolle Qualität, dafür ist er klein genug, um zum Beispiel in einem selbstgedruckten 3D-Gehäuse Platz zu finden.

Bei modernen Smartphones werden kapazitive Touchscreens eingesetzt. Das Cheap Yellow Display ist auch mit einem kapazitiven Digitizer zu haben, dann aber teurer. Dafür hat ein keine so wabbelige Oberfläche und es muss kein Druck ausgeübt werden. Allerdings muss man ihn prinzipbedingt mit dem nackten Finger oder einem weiterleitenden Gegenstand berühren, damit er die Position erkennen kann. Man kann den Unterschied zwischen resistiven und kapazitiven Digitizer mit einem Drucktaster und einer Sensortaste vergleichen.

Was soll das Demoprogramm können?

Um den Touchscreen auch gleich testen zu können, schreibe ich heute ein kleines Demoprogramm, welches folgendes bewerkstelligen können soll:

Die PlatformIO.ini als Dreh- und Angelpunkt der Konfiguration

Die platformio.ini war ja schon immer unsere Konfigurationsdatei. Doch man kann noch viel mehr darüber konfigurieren, als wir bisher getan haben. Zum Beispiel können wir damit die UserSetup.h für die eSPI_TFT-Library loswerden.

Aber stürzen wir uns gleich ins kalte Wasser und schauen uns die neue platformio.ini an, Erklärungen erfolgen umgehend:
[platformio] src_dir = . default_envs = cyd_v3 [env] platform = espressif32@6.5.0 board = esp32dev framework = arduino upload_speed = 460800 upload_port = COM17 monitor_speed = 115200 monitor_port = COM17 lib_deps = bodmer/TFT_eSPI@^2.5.43 ; https://github.com/Bodmer/TJpg_Decoder https://github.com/PaulStoffregen/XPT2046_Touchscreen build_flags = ; anstatt User_Setup.h für TFT_eSPI Library -D USER_SETUP_LOADED -D ILI9341_2_DRIVER -D TFT_WIDTH=240 -D TFT_HEIGHT=320 -D USE_HSPI_PORT -D TFT_MISO=12 -D TFT_MOSI=13 -D TFT_SCLK=14 -D TFT_CS=15 -D TFT_DC=2 -D TFT_RST=-1 -D TFT_BL=21 -D TFT_BACKLIGHT_ON=HIGH -D TFT_BACKLIGHT_OFF=LOW -D LOAD_GLCD -D LOAD_FONT2 -D LOAD_FONT4 -D LOAD_FONT6 -D LOAD_FONT7 -D LOAD_FONT8 -D LOAD_GFXFF -D SMOOTH_FONT ;-D SPI_FREQUENCY=27000000 -D SPI_FREQUENCY=55000000 -D SPI_READ_FREQUENCY=20000000 -D SPI_TOUCH_FREQUENCY=2500000 ; für XPT2046_Touchscreen Library -D XPT2046_IRQ=36 -D XPT2046_MOSI=32 -D XPT2046_MISO=39 -D XPT2046_CLK=25 -D XPT2046_CS=33 ; XPT2046 Digitizer X/Y min und max -D XPT2046_XMIN=290 -D XPT2046_XMAX=3670 -D XPT2046_YMIN=230 -D XPT2046_YMAX=3860 ; Lichtsensor-Pin -D LDR_PIN=34 [env:cyd_v1] build_flags = ${env.build_flags} -D CYD_VARIANT=v1 -D TFT_INVERSION_OFF [env:cyd_v3] build_flags = ${env.build_flags} -D CYD_VARIANT=v3 -D TFT_INVERSION_ON
Um zwischen der ESP32-2432S028 Variante nur mit Micro-USB (v1) und der mit Micro-USB und USB-C (v3) schnell umschalten zu können, definiere ich ganz unten die beiden Umgebungen [env:cyd_v1] und [env:cyd_v3]. Dort werden jeweils die gemeinschaftlichen build_flags integriert und die unterschiedlichen build_flags je nach Umgebung anders definiert. Dann muss ich nämlich nur noch ganz oben bei default_envs "cyd_v1" oder "cyd_v3" eintragen, um für die eine oder die andere Variante zu kompilieren.

Wobei wir bei den build_flags wären: mit "-D ..." kann ich Define-Statements definieren, die wie ein #define im Source-Code wirken. Das Define-Statement gebe ich einfach nach dem "-D" ein. Das Leerzeichen muss allerdings durch ein "=" ersetzt werden und Kommentare mit ";" hinter den Statements sind nicht erlaubt (bzw. werden in das Define-Statement übernommen, was beim Kompilieren zu Syntaxfehlern führt).

Die ganzen #defines aus unserer User_Setup.h (siehe letzten Artikel), die aktiv sind, werden jetzt in die build_flags übernommen und wir können uns die User_Setup.h sparen.

Das gleiche machen wir auch für die Werte unserer heute neu genutzten XPT2046_Touchscreen Library (dazu gleich) und geben dort die Pins des zweiten SPI-Interfaces für den XPT2046-Digitizer an mit XPT2046_IRQ, XPT2046_MOSI, XPT2046_MISO, XPT2046_CLK und XPT2046_CS.

So können wir alles an einer Stelle definieren, was die Sache sehr viel übersichtlicher macht. Wollen wir ab jetzt Dinge, die die Board-Variante betreffen, ändern, so wissen wir, wir müssen nur die platformio.ini ändern und müssen uns nicht mit mehreren Konfigurationsdateien herumschlagen.

Ich hatte ja schon erwähnt, dass die Werte, die der XPT2046 liefert, nicht genau bei 0 anfangen und bei 4095 aufhören. Vielmehr gibt es einen kleinen, unsichtbaren Tot-Rahmen um den Screen, und die Werte fangen so ca. bei 260 an und hören bei 3800 auf.

Aber genau diese Werte wollen wir ja mit unserem Demoprogramm herausfinden und können sie dann hier als XPT2046_XMIN, XPT2046_XMAX, XPT2046_YMIN und XPT2046_YMAX eintragen, damit die Position von XTP2046 und Display auch gut übereinstimmen.

Und als letztes definieren wir mit LDR_PIN noch den Pin, den unser Cheap Yellow Display für die Messung des Lichtsensors auf der Vorderseite unten links (wenn der USB Port unten rechts ist) benutzt. Der LDR erkennt man an der kleinen, geschlängelten Linie.

Kurzer Ausflug in die Hardware des LDR


Der LDR, also ein Fotowiderstand ist von Typ GT36516 und dieser soll laut Datasheet einen Widerstandswert zwischen 300 kΩ (wenn dunkel) und ca. 7.5 kΩ wenn die Helligkeit bei 10 Lux liegt, liefern. Das Maximum für 10 Lux ist mit 10 kΩ angegeben.

Die Werte des LDR werden durch einen Spannungsteiler ermittelt. Denn wir können nicht den Widerstand, den der LDR liefert direkt messen, sondern wir können nur Spannungen am Analog-Eingang messen. Darum brauchen wir eine Spannungsteiler-Schaltung. Für das Grundverständnis empfehle ich meinen Artikel Fotowiderstand mit Arduino auslesen und über serielle Schnittstelle darstellen. Wenn man also den Messbereich möglichst ausschöpfen möchte, um eine möglichst hohe Genauigkeit zu erreichen, dann wählt man am besten einen Zweit-Widerstand, der ungefähr dem Wert des durch den LDR gemessenen Widerstands im gewünschten Bereich entspricht. Will ich also bis 10 Lux messen und nicht mehr, wähle ich hier bei max. 10 kΩ durch den LDR auch einen 10 kΩ Zweitwiderstand. So kann ich alles zwischen 0 und 10 Lux besonders fein messen, denn die 10 Lux werden einen Messwert von 0 ergeben und bei Dunkelheit werden es 4095 sein.

Will ich auch Unterschiede über 10 Lux messen können, dann wähle ich einen höheren Wert, vielleicht 100 kΩ. Je nach Widerstandsverlaufkurve kann ich dann bis 100 Lux, vielleicht auch 1000 oder 10'000 oder 100'000 Lux messen. An einem sehr hellen Sommertag, mit uneingeschränktem Sonnenschein, kann im Freien auch schon mal ein Lux-Wert von 100'000 gemessen werden. Will ich das auch abdecken, nehme ich vielleicht einen noch höheren Widerstand. Das kommt aber auf den Versuch und Messungen des LDR an, denn der Widerstandsverlauf ist nicht linear und das Data Sheet gibt keine nähere Auskunft zum Verlauf.

Die verbauten Widerstände R15 und R19 (siehe Foto) hat allerdings einen Widerstandswert von 1'000'000 Ω (Aufschrift 105 entspricht 10 plus 5 Nullen), also 1 MΩ, was viel zu viel ist, wie die Praxis zeigt. Denn der LDR zeigte bei mir eigentlich immer nur Null an und geht erst gerungfügig hoch, wenn ich ihn komplett zuhalte. Hier wären sicher 100 kΩ Widerstände eher angebracht, damit man auch die Umgebungshelligkeit messen kann. So ist der LDR jedenfalls ziemlich nutzlos, um das Umgebungslicht zu messen, um damit die Displayhelligkeit zu messen.

Damit hätten wir die neue platformio.ini durch. Bis auf den Eintrag mit der neuen Library für den XPT2046-Digitizer.

Die Library XPT2046_Touchscreen

Wie im letzten Artikel bereits erwähnt, geht die TFT-eSPI-Library immer vom gleichen SPI-Interface für den Digitizer aus wie für das Display benutzt wird, lediglich TOUCH_CS kann definiert werden, um zwischen Display und Digitizer-Abfrage umzuschalten.

Wir haben aber zwei komplette SPI-Interfaces auf unserem CYD, eines für das Display, und eines für den Digitizer. Die TFT-eSPI-Library können wir deswegen leider nicht aus für den Digitizer benutzen, sondern brauchen eine Library, mit der wird die SPI-Pins für den Digitizer mitgeben können.

Für den in unserem Touchscreen-ESP32 verbauten XPT2046-Digitizer gibt es von Paul Stoffregen die passende Library, die wir mit der Zeile "lib_deps = https://github.com/PaulStoffregen/XPT2046_Touchscreen" einbinden. Die ist schon ein bisschen älter, und es war nicht einfach die richtige Version zu finden, aber mit der angegebenen Zeile wird die richtige Library-Version gefunden.

Die liefert für X und Y Position Werte zwischen 0 und 4095. Diese Werte müssen dann noch auf das Koordinatensystem von 0 bis 319 für X und 0 bis 239 für Y auf dem Display umgerechnet werden, damit wir eine Beziehung zwischen Digitizer und Display haben und wissen, wo auf der Grafik auf dem Display geklickt wurde. Dazu gibt es in der Library die Funktion readData(&x, &y, &z), wobei dann die Druckstärke in die Variable z (uint16_t, wie auch x und y) geschrieben wird.
Oder man verwendet etwas eleganter TS_Point p = ts.getPoint(), wobei p ein Struct ist, das x, y und z beinhaltet. Abzufragen zum Beispiel mit x.p .

Außerdem bietet die Library die Funktion touched(), die true oder false zurückgibt und mit der wir schnell checken können, ob jemand auf den Touchscreen getappt hat. Hat das Display eine Interrupt-Leitung wie das CYD (XPT2046_IRQ=36), dann können wir diesen Pin bei der Objekterstellung der XPT-Objektes mitgeben XPT2046_Touchscreen xpt(XPT2046_CS, XPT2046_IRQ); und können dann auch die Funktion xpt.tirqTouched() benutzen.

Der eigentlich Gag des Interrupts aber ist es, dass der Touchscreen von sich aus einen Interrupt-Event auslöst und wir damit zum Beispiel das CYD aus dem Sleep-Mode aufwecken können oder eine Interrupt-Routine mit
SPI.usingInterrupt(digitalPinToInterrupt(pin)) attachInterrupt(digitalPinToInterrupt(XPT2046_IRQ), myFunction, FALLING);
definieren können, die dann immer aufgerufen wird, wenn auf den Touchscreen getippt wird. Das ist praktischer, um Tipp-Event abzufangen statt sie in einer Endlosschleife abzufragen. Hier ist allerdings zu beachten, nicht außerhalb der Interrupt-Routine die Touch-Position auszulesen, denn jede Positionsauslesung löst auch einen Interrupt aus. Also muss vor dem Auslesen kurz der Interrupt-Vektor gelöscht, und nach dem Auslesen wieder gesetzt werden, damit es nicht zu einer Endlosschleife {Interrupt -> Read -> Interrupt -> ...} kommt.

Für den Anfang ist die Dauerabfrage von isTouched() wohl einfacher als das benutzen des Interrupts, der wahrscheinlich schneller reagiert.

Das ist auch schon alles, was wir zum Umgang mit der Library wissen müssen:

Wechsel der Modi im Demoprogramm via Fotowiderstand (LDR)

Da wir zwei Modi im Demoprogramm haben, nämlich einmal die Anzeige der Position zur Kalibrierung und zum anderen den Mal-Modus, brauchen wir etwas, um von Modus 1 zu Modus 2 weiterzuschalten.

Man könnte ein kleines Kästchen zum antippen zeichnen und dann weiterschalten, aber das würde irgendwie auch stören. Weniger störend und noch einfacher ist es doch, einfach den LDR, den Lichtsensor auf der Vorderseite, links unten abzufragen. Wenn der durch den Finger oder etwas anderes verdeckt wird, dann bekommt er kein Licht mehr und dass können wir abfragen.

Das geht so einfach, dass wir nicht einmal eine Library dafür brauchen. Denn das geht ganz einfach mit pinMode(LDR_PIN, INPUT) und int ldr = analogRead(LDR_PIN) und schon haben wir einen 12-bit-Wert (0...4095), wobei Totale Dunkelheit bei 4095 sein sollte. Dummerweise ist - wie oben erwähnt - der Widerstand auf dem CYD falsch und wir bekommen deswegen nur schwierig Werte über Null (eigentlich hell wie die Sonne). analogSetAttenuation(ADC_0db) hilft da ein wenig, weil es die Empfindlichkeit der Messung heraufsetzt, aber bei einem CYD reicht dann immer noch nicht der Finger, sondern ich muss einen Gegenstand zum Abdunkeln nehmen.

Aber das ist, wie bereits erwähnt, ein Hardware-Problem. Zum Weiterschalten soll uns das trotzdem erst einmal taugen.

Source-Code

Der Source-Code für das Demoprogramm fasst die bereits erwähnten Funktionen zusammen. Klicke auf das kleine Dreieck, um ihn auszuklappen und zu lesen. Da der Code gut dokumentiert ist (auf englisch) und bereits im Groben erläutert (siehe oben, in deutsch), spare ich mir die Erklärung der einzelnen Code-Zeilen.

main.cpp (klicken, um diesen Abschnitt auf- und zuzuklappen)
// V1.00, 2024-04-04 // (C) by Oliver Kuhlemann, cool-web.de // Quelle: https://cool-web.de/esp8266-esp32/ #include <Arduino.h> #include <SPI.h> #include <XPT2046_Touchscreen.h> #include <TFT_eSPI.h> SPIClass mySpi = SPIClass(VSPI); // SPI-Interface for XPT2046_Touchscreen XPT2046_Touchscreen xpt(XPT2046_CS, XPT2046_IRQ); // create an XPT object (Digitizer) TFT_eSPI tft = TFT_eSPI(); // create an TFT object (TFT-Display) // read position of XPT digitizer and corresponding TFT position void xptPosition (uint16_t *xptX, uint16_t *xptY, uint8_t *xptZ, uint16_t *tftX, uint16_t *tftY) { uint16_t x, y; uint8_t z; // XPT uint16_t tx, ty; // TFT float xx = (XPT2046_XMAX - XPT2046_XMIN); // width XPT-Points float yy = (XPT2046_YMAX - XPT2046_YMIN); // height XPT-Points xpt.readData(&x, &y, &z); // calc position for TFT display from digitizer position tx = (x / xx * TFT_HEIGHT) - (XPT2046_XMIN / xx * TFT_HEIGHT); // TFT_HEIGHT=320 ty = (y / yy * TFT_WIDTH) - (XPT2046_YMIN / yy * TFT_WIDTH); // TFT_WIDTH=240 // avoid invalid values if (tx < 0) tx = 0; if (ty < 0) ty = 0; if (tx > TFT_HEIGHT-1) tx = TFT_HEIGHT-1; if (ty > TFT_WIDTH-1) ty = TFT_WIDTH-1; *xptX = x; *xptY = y; *xptZ = z; *tftX = tx; *tftY = ty; } void setup() { Serial.begin(115200); // Start the SPI for the touch screen and init the XPT2046 library mySpi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); xpt.begin(mySpi); xpt.setRotation(1); // landscape, USB ports right bottom tft.init(); tft.setRotation(1); // landscape, USB ports right bottom tft.fillScreen(TFT_BLACK); // clear screen int y=60; int lh=30; // y-pos 1. line, line-height tft.drawCentreString("Touch Screen to Start", TFT_HEIGHT/2, y, 4); y+=lh*2; tft.drawCentreString("Then shadow LDR and", TFT_HEIGHT/2, y, 4); y+=lh; tft.drawCentreString("tap for next mode...", TFT_HEIGHT/2, y, 4); y+=lh; analogSetAttenuation(ADC_0db); // Increase read sensitivity of light sensor pinMode(LDR_PIN, INPUT); } void loop() { uint16_t xptX, xptY, tftX, tftY; uint8_t xptZ; uint16_t xptX_max = 0; uint16_t xptY_max = 0; uint16_t xptX_min = 4095; uint16_t xptY_min = 4095; while (1) { if (xpt.touched()) { // if screen tapped // get position for XPT digitizer and TFT xptPosition (&xptX, &xptY, &xptZ, &tftX, &tftY); if (xptX > xptX_max) xptX_max = xptX; if (xptY > xptY_max) xptY_max = xptY; if (xptX < xptX_min) xptX_min = xptX; if (xptY < xptY_min) xptY_min = xptY; // write values to display tft.fillScreen(TFT_BLACK); // clear screen tft.setTextColor(TFT_WHITE, TFT_BLACK); int y=30; int lh=30; // y-pos 1. line, line-height String strg = "Pressure = " + String(xptZ); tft.drawCentreString(strg, TFT_HEIGHT/2, y, 4); y+=lh; strg = "XPT_X = " + String(xptX) + ", TFT_X = " + String(tftX); tft.drawCentreString(strg, TFT_HEIGHT/2, y, 4); y+=lh; strg = "XPT_Y = " + String(xptY) + ", TFT_Y = " + String(tftY); tft.drawCentreString(strg, TFT_HEIGHT/2, y, 4); y+=lh; strg = "XPT_X = " + String(xptX_min) + " ... " + String(xptX_max); tft.drawCentreString(strg, TFT_HEIGHT/2, y, 4); y+=lh; strg = "XPT_Y = " + String(xptY_min) + " ... " + String(xptY_max); tft.drawCentreString(strg, TFT_HEIGHT/2, y, 4); y+=lh; // check LDR-value and if LDR is pitch dark, exit loop and go on with next mode int ldr = analogRead(LDR_PIN); strg = "Light Sensor = " + String(ldr); tft.drawCentreString(strg, TFT_HEIGHT/2, y, 4); y+=lh; if (ldr > 100) break; delay(100); } } // end while tft.fillScreen(TFT_BLACK); //CLS while (1) { xptPosition (&xptX, &xptY, &xptZ, &tftX, &tftY); // set a pixel on touched position tft.drawPixel(tftX, tftY, TFT_YELLOW); } }

Zweck des Testprogrammes


Nach dem Start und einmal Tippen auf den Touchscreen zeigt das Display bei jedem Touch - man kann auch gedrückt halten - die aktuelle Position des XPT2046-Digitizers (XPT_X/Y, von 0 bis 4095) und die auf das Display umgerechnete Position (TFT_X/Y, von 0 bis 320 bzw. 240) an. Zudem wird die Druckstärke (Pressure, von 0 bis 255) und der Wert für den Licht Sensor (von 0 = grell bis 4095 = absolute Finsternis) angezeigt.

Nun tippt man mit dem Fingernagel oder dem Eingabe-Stift in die vier Ecken oder bewegt sich von ganz links bis ganz rechts und von ganz oben bis ganz unten, wobei die Minimal und Maximal-Werte erfasst werden. Vorsicht! Eventuell ist das X/Y-Minimum/Maximum in der Mitte der Kanten kleiner bzw. größer als es an den Ecken möglich wäre, dann sollte man die Eckwerte nehmen.

Die Min- und Maxwerte gehören in die platform.ini in die Zeilen
-D XPT2046_XMIN=290 -D XPT2046_XMAX=3670 -D XPT2046_YMIN=230 -D XPT2046_YMAX=3860
Danach ist das Programm neu zu kompilieren und hochzuladen.




Mit einem Tipp auf den Screen, bei dem man den Lichtsensor zuhält, geht es in den Mal-Modus. Dieser dient der Überprüfung der Positionsbestimmung der Koordiante für das Display selbst (320 x 240 Pixel). Für die Berechnung werden die Min/Max-Werte des XPT herangezogen.

Tippe einmal irgendwo hin und schau, ob genau dort, wo du hingetippt hast ein gelber Punkt erscheint. Noch schöner und ersichtlicher wird es, wenn man den Stift heruntergedrückt hält und umhergewegt.

Wird an den Stellen gemalt, wo sich auch der Stift befindet? Falls ja: wunderbar, jetzt sollte es sogar leichtfallen, etwas auf den Screen zu schreiben. Falls nein: Resette den Touchscreen-ESP32 und bekomme ein Gefühl für die richtigen Werte, die du in die platformio.ini einträgst. Danach neu kompilieren, hochladen und wieder testen.

Nach nicht allzuvielen Versuchen solltest du mit dem Ergebnis zufrieden sein. Ich habe die Werte mit meinem CYD v3 ermittelt und schon einmal vorab eingetragen. Allerdings ohne Garantie, dass die Werte exakt so für alle Touch-Screens passen. Wahrscheinlich kommt es darauf an, wie genau die XPT2046-Digitizer-Folie auf dem darunterliegenden ILI9341-Display geklebt wurde.

Kleine Abweichungen sind vorstellbar. Bei meinem CYD v1 haben die Werte meines CYD v3 aber gut gepasst. Wer es ganz genau braucht, muss pro CYD kompilieren oder schreibt eine Kalibrierungssoftware, die man innerhalb der Firmware aufrufen kann und die Daten auf der SD-Karte speichert, damit man nicht jedesmal neu kalibrieren muss.

Firmware Download via ESP Web Tools

Du möchtest die Firmware schon einmal ausprobieren, ohne die Entwicklungsumgebung zu installieren oder zu programmieren?

Kein Problem. Schließe einfach dein ESP32 an einen USB-Port deines PC an und klicke auf den deinem Gerät entsprechenden Button:

Die Firmware-Installation funktioniert leider nur mit Google Chrome und Chromium-basierten Browsern wie Microsoft Edge, Opera, Vivaldi oder Brave; jedoch nicht mit Firefox. Bitte benutze eine HTTPS-Verbindung, HTTP funktioniert nicht.

Die Firmware-Installation funktioniert leider nur mit Google Chrome und Chromium-basierten Browsern wie Microsoft Edge, Opera, Vivaldi oder Brave; jedoch nicht mit Firefox. Bitte benutze eine HTTPS-Verbindung, HTTP funktioniert nicht.

Demo und Video

Und hier noch ein kleines Video, das das Ganze noch einmal in bewegtem Bild zusammenfasst:


Fazit und Aussichten

Nun können wir Dinge auf dem Display darstellen und auch herausfinden, wenn und wo jemand auf den Screen tippt. Damit könnten wir im Prinzip unsere eigenen Dialoge zusammen basteln.

Da es aber schon etwas fertiges gibt, das einen sehr professionellen Eindruck macht, wollen wir beim nächsten mal die LVGL-Library testen. Die kennen wir schon aus der Dialog-Demo, die anfangs auf unserem gekauften Gerät drauf war. Wär doch toll, etwas eigenes in diesem Stil machen zu können, oder?

Quellen, Literaturverweise und weiterführende Links