#ESP32DevelopmentBoard
Explore tagged Tumblr posts
draegerit · 1 year ago
Text
Neues Spiel, neuer Spaß: Vier gewinnt auf dem ESP32 TFT-Display
Tumblr media
In diesem neuen Beitrag möchte ich dir gerne ein weiteres Spiel vorstellen, welches du recht einfach am ESP32 Development Board mit 2,8" TFT-Display nachprogrammieren kannst. Es ist "Vier gewinnt!", das Spiel gibt es in diversen offline Varianten und wirst du bestimmt bereits kennen und gespielt haben. https://youtu.be/fFLct1JabOk
Ziel des Spieles "Vier gewinnt!"
Das Ziel des Spiels "Vier gewinnt!" ist es, als erster Spieler vier seiner Spielsteine in einer horizontalen, vertikalen oder diagonalen Linie zu platzieren. Die Spieler wechseln sich ab, indem sie abwechselnd einen Spielstein in eine der vertikalen Spalten des Spielbretts fallen lassen. Der Spieler, der zuerst eine ununterbrochene Linie aus vier seiner Spielsteine bildet, gewinnt das Spiel. Es erfordert strategisches Denken, um die Spielsteine so zu platzieren, dass man entweder eine eigene Linie vervollständigt oder gleichzeitig die des Gegners blockiert.
Tumblr media
Spielfläche - Vier gewinnt am ESP32 Development Board
Tumblr media
gesetzter Spielstein bei Vier gewinnt am ESP32 TFT Display
Tumblr media
Spieler Gelb hat beim Spiel Vier gewinnt gewonnen!
Tumblr media
Spieler Rot hat beim Spiel Vier gewinnt gewonnen!
Benötigte Ressourcen für die Programmierung am ESP32 Development Board
Wenn du dieses kleine Spiel nachprogrammieren möchtest, dann benötigst du: - ein ESP32 Development Board (LVGL, ESP32-2432S028)*, - ein Datenkabel, Eingabestift, - die Arduino IDE Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Schritt-für-Schritt-Anleitung zum Programmieren von Vier gewinnt am ESP32 mit TFT-Display
Nachfolgend nun die Schritt-für-Schritt-Anleitung zum programmieren von Vier gewinnt am ESP32 Development Board. Wenn du dich jedoch nur für das fertige Spiel interessierst, dann kannst du dir dieses auch als ZIP-Datei herunterladen. Quellcode - Vier gewinnt am ESP32 Development BoardHerunterladen Besonderheiten & Vorwort Bevor wir mit der Programmierung beginnen möchte ich dir zunächst einpaar Hinweise an die Hand geben. Zum einen habe ich hier einen ansatz gewählt welcher deutlich weniger Speicher benötigt. Das musste ich zum einen weil die Bibliothek für das TFT-Display schon alleine recht groß ist und zum anderen wenn die Daten des Spielfeldes abgelegt werden diese dann unnötig Platz verbrauchen. Zusätzlich habe ich hier ChatGPT benutzt um den Quellcode zu erstellen. Mit den richtigen Prompts kann die künstliche Intelligenz eine sehr gute Unterstützung sein. Schritt 1 - zeichnen der Spielfläche Zunächst zeichnen wir die Spielfläche. Dazu gehört die Überschrift "Vier gewinnt" sowie die blaue Fläche mit den Pfeilen und schwarzen Kreisen.
Tumblr media
Spielfläche - Vier gewinnt am ESP32 mit TFT-Display Die Pfeile zeichne ich in einer Funktion und speichere die Informationen (Index / Spalte, X & Y Koordinate) in einem Array. //Feld für die Daten eines Pfeiles struct Arrow { int col; int x; //X Koordinate int y; //Y Koordinate }; //Array für die Pfeile //das Array wird beim zeichnen befüllt Arrow arrowFields = {}; //Funktion zum zeichnen der Spielfläche void drawPlayground() { //leeren des Displays lcd.clear(); //Hintergrundfarbe Schwarz lcd.fillScreen(TFT_BLACK); //Schriftgröße 4 lcd.setFont(&fonts::Font4); //Schriftfarbe Gelb, //Hintergrundfarbe Schwarz lcd.setTextColor(TFT_YELLOW, TFT_BLACK); //Text an die Position x & y schreiben lcd.drawString("Vier gewinnt!", 105, 5); //ein blaues rechteck zeichnen lcd.fillRect(40, 35, 255, 205, TFT_BLUE); // For-Schleife zum Zeichnen von sieben Dreiecken for (int i = 0; i < 7; i++) { // Koordinaten für die Eckpunkte des Dreiecks berechnen int x1 = startX + (i * (triangleWidth + spacing)); int y1 = startY; int x2 = x1 + triangleWidth / 2; int y2 = startY + (triangleWidth / 2); int x3 = x1 + triangleWidth; int y3 = startY; // fillTriangle-Funktion aufrufen, um das Dreieck zu zeichnen lcd.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN); Arrow arrowField = {i, x1, y1}; arrowFields = arrowField; } //zeichnen des Arrays drawHoles(); //anzeigen der Daten auf dem Display lcd.display(); } Die schwarzen Kreise werden später mit den gesetzten Spielsteinen befüllt. Hier speichere ich keine Daten ab denn die Berechnung der X & Y Koordinate für einen Kreis erfolgt anhand eines der Pfeile. (Wenn der Spieler eines der grünen Pfeile betätigt dann wird die Spalte und die X & Y Koordinate ermittelt.) //Anzahl der Spalten const int COLS = 7; //Anzahl der Zeilen const int ROWS = 5; //Das Array mit dem Spielfeld //initial sind alle Felder leer //bzw. mit einem Strich markiert char playground = { {DASH, DASH, DASH, DASH, DASH, DASH, DASH}, {DASH, DASH, DASH, DASH, DASH, DASH, DASH}, {DASH, DASH, DASH, DASH, DASH, DASH, DASH}, {DASH, DASH, DASH, DASH, DASH, DASH, DASH}, {DASH, DASH, DASH, DASH, DASH, DASH, DASH} }; //Funktion zum zeichnen der Daten des Arrays void drawHoles() { //ein gefülltes, blaues rechteck über die Spielfläche zeichnen //damit werden alle zuvor gezeichneten Daten überschrieben lcd.fillRect(40, 60, 255, 185, TFT_BLUE); //Schleife über das Array for (int col = 0; col < COLS; col++) { Arrow arrowField = arrowFields; for (int row = 0; row < ROWS; row++) { //Berechnen der X & Y Koordinate für das Loch int circleY = (startY + triangleWidth + circleSpacing + (2 * circleRadius + circleYspacing) * row) - 10; // y-Koordinate des Kreises int circleX = arrowField.x + triangleWidth / 2; // x-Koordinate des Kreises lcd.fillCircle(circleX, circleY, circleRadius, TFT_BLACK); //Wenn an der Koordinate im Array kein Strich ist, dann ist dort ein Spielstein abgelegt if (playground != DASH) { //den Spielstein zeichnen drawStone(circleX, circleY, playground == PLAYER1_CHAR); } } } } Zusätzlich prüfe ich in der Funktion drawHoles auch ob in dem Array playground ein Spielstein an der Position gesetzt ist. Wenn dieses so ist dann wird an die Position zusätzlich der entsprechende Spielstein gezeichnet. //Zeichnet ein Spielstein an die Position X & Y //der boolsche Parameter player1 gibt an ob Gelb oder Rot am zug ist void drawStone(int x, int y, bool player1) { //initial ist Gelb gesetzt uint8_t colorRingOuter1 = lcd.color332(137, 121, 5);; uint8_t colorRingOuter2 = lcd.color332(238, 226, 146); uint8_t colorRingInner = lcd.color332(243, 212, 0); //bei Spieler 2 soll ein Stein in der Farbe Rot gezeichnet werden. if (!player1) { colorRingOuter1 = lcd.color332(106, 5, 13); colorRingOuter2 = lcd.color332(239, 109, 119); colorRingInner = lcd.color332(255, 0, 0); } //zeichnen des Spielsteins lcd.fillCircle(x, y, 15, colorRingOuter1); lcd.fillCircle(x, y, 12, colorRingOuter2); lcd.fillCircle(x, y, 8, colorRingInner); } Das macht die Funktion multifunktional denn wir können mit dieser eine die komplette Spielfläche neu zeichnen und sparen somit Speicherplatz und der Code wird auch reduziert. Schritt 2 - setzen eines Spielsteines Das Spiel ist für zwei Spieler ausgelegt und diese setzen nacheinander jeweils einen Spielstein. Zum setzen eines Spielsteins in eine Zeile wird eines der grünen Pfeile betätigt. Es wird dann der letzte freie Platz der Spalte ermittelt und in diese eines der Steine gesetzt.
Tumblr media
gesetzter Spielstein im Spiel Vier gewinnt Bevor wir jedoch einen Spielstein setzen können, müssen wir den klick auf eines der Pfeile erkennen. Dieses machen wir wie beim Spiel Tic-Tac-Toe in der Funktion Loop. void loop() { //Wenn ein Touchaktion ausgeführt / erkannt wurde, //dann liefert die Funktion getTouch den Wert 1 und //befüllt die übergebenen Parametern mit den Koordinaten if (lcd.getTouch(&x, &y) == 1) { //Wenn die ermittelte X oder Y Positon außerhalb der Range ist, //dann soll die Funktion hier verlassen werden. if (x > MAX_X || y > MAX_Y) { return; } //Wenn das Spiel beendet ist, dann... if (gameOver) { //initialisiern der Spielfläche initPlayground(); drawPlayground(); //Feld wieder auf false setzen gameOver = false; } else { //Wenn das Spiel noch läuft, dann... //Variable zum speichern ob ein Pfeil geklickt wurde bool playerChooseArrow = false; //Variable zum speichern ob ein leeres Feld in der Spalte gefunden wurde bool foundEmptyPlace = false; //Schleife über alle Pfeile for (int arrow = 0; arrow < COLS; arrow++) { Arrow arrowField = arrowFields; //prüfen ob der Pfeil an der Position aus dem Array geklickt wurde if (checkCoord(arrowField, x, y)) { //Variable auf true setzen playerChooseArrow = true; for (int row = ROWS - 1; row >= 0; row--) { //prüfen ob das Feld leer / mit einem Strich belegt ist if (playground == DASH) { //Umkehren des Wertes für den Spieler currentPlayer1 = !currentPlayer1; //bei Spieler 1 soll ein X und bei Spieler 2 ein O an die Stelle im //Array gespeichert werden playground = currentPlayer1 ? PLAYER1_CHAR : PLAYER2_CHAR; //Es wurde ein leeres Feld gefunden und somit Variable auf true setzen foundEmptyPlace = true; //Schleife abbrechen break; } } } } //Wenn ein leeres Feld gefunden wurde, //und ein Pfeil gewählt wurde, dann... if (foundEmptyPlace && playerChooseArrow) { //zeichnen des Arrays drawHoles(); //prüfen ob der aktuelle Spieler gewonnen hat char player = currentPlayer1 ? PLAYER1_CHAR : PLAYER2_CHAR; if (hasPlayerWon(player)) { String playerColor = currentPlayer1 ? "Gelb" : "Rot"; displayMessage("Der Spieler " + playerColor + " hat gewonnen!", 0); gameOver = true; } else if (isGameDraw()) { displayMessage("Das Spiel ist unentschieden!", 40); gameOver = true; } } //eine kleine Pause von 300 ms. //Damit wird dem Spieler die möglichkeit gegeben //den Stift vom Display zu nehmen. delay(300); } } //eine Pause von 50ms. delay(50); } Schritt 4 - ermitteln ob ein Spieler gewonnen hat Wenn ein Spieler einen Spielstein gesetzt hat, dann wird zusätzlich auch geprüft ob dieser Spieler gewonnen hat oder es sogar ein unentschieden gibt. // Funktion, die prüft, ob ein Spieler gewonnen hat bool hasPlayerWon(char player) { // Überprüfen von horizontalen Linien for (int row = 0; row < ROWS; row++) { for (int col = 0; col Read the full article
0 notes
draegerit · 1 year ago
Text
ESP32 Development Board: Touchfunktion programmieren
Tumblr media
Im nun zweiten Teil zum ESP32 Development Board möchte ich dir gerne zeigen, wie die Touchfunktion des Displays in der Arduino IDE programmiert wird. Im ersten Teil habe ich dir das Board bereits ausführlich vorgestellt und gezeigt, wie du Grafiken und Texte auf dem Display anzeigen kannst. https://youtu.be/297BbK3MxL0 Dieser Beitrag ist wie erwähnt die Fortführung des Beitrages ESP32 Development Board mit 2,8 Zoll Touch Display: Programmieren für Anfänger ich gehe im nachfolgenden davon aus, dass du das Board bereits bei dir eingerichtet und betriebsbereit hast. Sollte dieses jedoch nicht so sein, so empfehle ich dir zunächst einen Blick in den zuvor verlinkten Beitrag.
Tumblr media Tumblr media
Pinbelegung des Touchfeldes vom ESP32 Development Board
Schauen wir uns zunächst die Pinbelegung des Touchfeldes an: BezeichnungPinCLKIO25CSIO33DIN / MOSIIO32OUT / MISOIO39IRQIO36 Das Board findest du sehr günstig auf Aliexpress.com zusätzlich findest du dort auch noch einen Schaltplan, aus welchem du weitere Informationen entnehmen kannst.
Programmieren des Touchfeldes in der Arduino IDE
Wie im Beitrag zuvor möchte ich das TFT Display in der Arduino IDE programmieren. Dazu benötigst du eine Bibliothek. Welche du über den internen Bibliotheksverwalter (1) installieren kannst. Wenn dieser geöffnet ist, dann suchst du zunächst nach "LovyanGFX" und wählst die Schaltfläche "INSTALLIEREN" (3).
Tumblr media
Zusätzlich zu dieser Bibliothek benötigen wir noch die Datei lgfx_ESP32_2432S028.h welche wir uns vom GitHub Repository OttoMeister / ARDUINO_ESP32-2432S028R herunterladen können. Probleme beim Upload Bevor wir mit der Programmierung beginnen, möchte ich dich auf eine Besonderheit mit dem Umgang der Bibliothek LovyanGFX in der Arduino IDE 2.0 hinweisen. Zum einen musste ich feststellen, dass der Upload zum Mikrocontroller sehr lange dauert (> 15 min.) und zum anderen manchmal mit dem Fehler "ping: timeout" abbricht. Als "Lösung" habe ich zur klassischen Arduino IDE 1.8.19 gewechselt, der Upload hier dauerte jedoch das erste mal etwas länger aber nach dem ersten Kompilieren dauerte der Vorgang dann nurnoch so knapp 30 Sekunden.
Beispiel - erkennen einer Berührung auf dem Display
Starten wir nun mit einem Beispiel und schreiben ein Programm, welches eine Berührung auf dem Touchdisplay erkennt und die X & Y Koordinate ausgibt. Der Code hierfür ist recht einfach, theoretisch müssen wir nur eine Funktion aufrufen und erhalten, ob ein Klick auf dem Display erfolgte und zusätzlich erhalten wir die Koordinaten. /* Einbinden der Bibliothek zum kommunizieren mit dem Display. */ #define LGFX_USE_V1 #include #include "lgfx_ESP32_2432S028.h" //Größe der Zeichenfläche definieren #define MAX_X 319 #define MAX_Y 239 //Felder für die ermittelte Position //bei einem klick uint16_t x = 0, y = 0; //Instanz des Displays static LGFX lcd; void setup(void) { //beginn der seriellen Kommunikation mit //115200 Baud Serial.begin(115200); //beginn der Kommunikation mit dem Display lcd.init(); //drehen des Displays lcd.setRotation(1); //füllen des Displays mit der Farbe Schwarz lcd.fillScreen(TFT_BLACK); //eine kleine Pause von 100ms. delay(100); } void loop() { //Wenn ein Touchaktion ausgeführt / erkannt wurde, //dann liefert die Funktion getTouch den Wert 1 und //befüllt die übergebenen Parametern mit den Koordinaten if (lcd.getTouch(&x, &y) == 1) { //befüllen des Displays mit der Farbe schwarz lcd.fillScreen(TFT_BLACK); //Wenn die ermittelte X oder Y Positon außerhalb der Range ist, //dann soll die Funktion hier verlassen werden. if (x > MAX_X || y > MAX_Y) { return; } //ein Kreuz an der X & Y Koordinate Zeichnen lcd.drawLine(x - 20, y, x + 20, y, 0xFFFF00U); lcd.drawLine(x, y - 20, x, y + 20, 0xFFFF00U); //setzen der Schriftart & Schriftgröße lcd.setFont(&fonts::Font2); //setzen des Cursors abhängig von der X/Y Koordinate setCursorPosition(0); //schreiben der X Position lcd.printf("x:%d", x); //setzen des Cursors abhängig von der X/Y Koordinate //mit einem Offset von 20 Pixel setCursorPosition(20); //schreiben der X Position lcd.printf("y:%d", y); //Zusätzlich werden die ermittelten Koordinaten auf der //Konsole ausgegeben. Serial.printf("x:%d,y:%d", x, y); } //eine Pause von 50ms. delay(50); } void setCursorPosition(int offset) { if (x < 280 && y < 200) { lcd.setCursor(x + 5, y + offset); } else { if (x > 280 && y > 200) { //|| y > 200 lcd.setCursor(x - 35, y - 40 + offset); } else if ((x < 20 && y > 200) || (x > 20 && y > 200)) { lcd.setCursor(x + 5, y - 40 + offset); } else if (x > 280) { lcd.setCursor(x - 35, y + offset); } } }
Ein Button Zeichnen und Touchfunktion hinterlegen
Wollen wir nun einen Button auf dem Display zeichnen und diesem eine Aktion hinterlegen. Dabei soll der Button sein Style ändern, wenn dieser gedrückt wird. Das Styling ist etwas rustikal, jedoch funktional. Für coole Dashboards gibt es andere Tools, welche ich dir noch separat in eigenen Beiträgen präsentieren möchte. Vorwort Meine Programme schreibe ich immer sehr dynamisch, d.h. es ist manchmal etwas mehr Code, aber dafür kann dieser deutlich besser wiederverwendet werden. Genau das mache ich in diesem Beispiel hier auch und erstelle mir ein struct welches die Eigenschaften für den Button speichert. //Eigenschaften eines Buttons definieren struct Button { bool isPressed; //ist dieser gedrückt? int coord_x; //X Koordinate int coord_y; //Y Koordinate int width; //Breite int height; //Höhe uint8_t backgroundcolor; //Hintergrundfarbe uint8_t textcolor; //Textfarbe String caption; //Text auf dem Button }; Wenn du das fertige Programm herunterladen möchtest, dann kannst du dieses über nachfolgenden Link machen oder auf mein GitHub Repository StefanDraeger / ESP32_Development_Board_ESP32-2432S028R. Programm - ESP32 Development Board - Buttons mit AktionHerunterladen einen Button mit Effekt programmieren Im ersten Schritt erstellen wir ein Rechteck mit abgerundeten Ecken und für den Schatten das gleiche nochmal in Grau. Somit hat man ein oldschool 3D Effekt. Ich habe mir zunächst 2 Buttons definiert (siehe das struct oben) und in ein Array hinterlegt, das macht es einfacher, wenn wir diese auswerten und zeichnen möchten (die Eigenschaften sind ja somit gleich bzw. wir haben diese als Attribute hinterlegt.) //definieren von zwei Buttons Button btn1 = { false, 20, 20, 50, 25, lcd.color332(255, 0, 0), lcd.color332(255, 255, 255), "Test" }; Button btn2 = { false, 20, 60, 100, 25, lcd.color332(0, 255, 0), lcd.color332(0, 0, 0), "Hallo Welt!" }; //die beiden Buttons in ein Array aufnehmen //das macht es später einfacher diese abzuarbeiten const int NUM_BUTTONS = 2; Button buttons = { btn1, btn2 }; //Offset für den Schatten des Buttons const int SHADOW_OFFSET = 2; Wie bereits erwähnt arbeite ich mit einem struct vom Typ Button, das ermöglicht es mir die Eigenschaften an einem "Objekt" zu speichern und dieses einfach einer Funktion zu übergeben. //Zeichnen eines Buttons void drawButton(Button button) { //Wenn der Button gedrückt ist, //dann soll der Schatten nach oben links zeigen if (button.isPressed) { lcd.fillRoundRect(button.coord_x - SHADOW_OFFSET, button.coord_y - SHADOW_OFFSET, button.width, button.height, 10, lcd.color332(176, 190, 197)); } else { //Wenn der Button nicht gedrückt ist, //dann soll der Schatten nach unten rechts zeigen lcd.fillRoundRect(button.coord_x + SHADOW_OFFSET, button.coord_y + SHADOW_OFFSET, button.width, button.height, 10, lcd.color332(176, 190, 197)); } //Zeichnen eines Rechtecks mit abgerundeten Ecken mit den Eigenschaften des Buttons lcd.fillRoundRect(button.coord_x, button.coord_y, button.width, button.height, 10, button.backgroundcolor); //Berechnen der Position für den Text. int textLenght = (button.caption.length() * 3); int newX = (button.width / 2) - (textLenght / 2) + 5; //setzen der Textfarbe und der Hintergrundfarbe lcd.setTextColor(button.textcolor, button.backgroundcolor); //positionieren des Cursors lcd.setCursor(button.coord_x + (newX / 2), button.coord_y + 8); //schreiben des Textes an die gesetzte Position lcd.print(button.caption); } Die Eigenschaft isPressed wird verwendet, um die Aktion auszuwerten, wenn der Button geklickt wird. Es soll zunächst der Schatten wechseln, damit wird optisch ein Drücken sichtbar. In der loop prüfen wir nun fortlaufend ob ein Button geklickt wurde. void loop() { //Wenn auf das Display geklickt wird, dann //liefert die Funktion getTouch eine 1 ansonsten 0 //zusätzlich werden die Koordinaten in die Felder //x & y gespeichert. if (lcd.getTouch(&x, &y) == 1) { //Wenn die Koordinaten außerhalb der Range sind, //dann soll die Funktion hier verlassen werden. if (x > MAX_X || y > MAX_Y) { return; } //Schleife über das Array mit den Buttons for (int i = 0; i < NUM_BUTTONS; i++) { //Button aus dem Array mit dem Wert aus //der Laufvariable i lesen. Button button = buttons; //Wenn die geklickte Position auf dem //Display innerhalb der Abgrenzung eines //Buttons ist, dann... if (checkCoordButton(button, x, y)) { //Togglen des Buttons toggleButton(button); } } } //eine Pause von 50 Millisekunden. delay(50); } An den Buttons haben wir die Koordinaten und Breite & Höhe hinterlegt, von der Funktion getTouch erhalten wir zusätzlich die geklickten Koordinaten. Mit der nachfolgenden Funktion prüfen wir dann ob sich die geklickte Koordinate auf dem Button befindet. //Prüfen ob die angeklickte Position auf dem Display innerhalb der Abgrenzung //des Buttons ist. bool checkCoordButton(Button button, int x, int y) { return (x >= button.coord_x && x = button.coord_y && y Read the full article
0 notes
draegerit · 1 year ago
Text
Tic-Tac-Toe Spaß auf dem ESP32: Ein Touchscreen-Spielprojekt
Tumblr media
Wie du ein Tic-Tac-Toe Spiel am ESP32 mit Touchscreen programmierst, erfährst du hier in meiner Schritt-für-Schritt-Anleitung. Ich nehme dich mit und zeige dir detaliert wie du dieses kleine Spiel in der Arduino IDE mit C/C++ programmierst. Es ist einfacher als du denkst. https://youtu.be/sJTSo61y_mw Bei Tic-Tac-Toe handelt es sich um ein einfaches Spiel für zwei Spieler, das auf einem 3x3-Raster gespielt wird. Jeder Spieler wählt abwechselnd ein Feld aus und versucht, eine Reihe von drei seiner eigenen Symbole horizontal, vertikal oder diagonal zu bilden. Auf dem ESP32 mit dem 2,8" TFT Touchdisplay wird das Spiel grafisch dargestellt, und die Spieler können ihre Züge durch Berühren der entsprechenden Felder tätigen. Das Programm überprüft kontinuierlich, ob ein Spieler gewonnen hat oder das Spiel unentschieden ist, und gibt entsprechende Rückmeldungen aus. Es ist ein unterhaltsames und interaktives Projekt, das die Funktionalitäten des ESP32 und des Touchscreens demonstriert.
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
Benötigte Ressourcen für dieses Spiel
Wenn du das kleine Spiel nachprogrammieren möchtest, dann benötigst du: - ein ESP32 Development Board*, - einen Stift (für den Touchscreen), - ein Datenkabel, - die Arduino IDE 2.3.x Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Programmieren von Tic-Tac-Toe am ESP32 mit der Arduino IDE
Das fertige Spiel kannst du dir entweder nachfolgend als ZIP-Datei oder von meinem GitHub Repository StefanDraeger/ESP32_Development_Board_ESP32-2432S028R herunterladen. (neben vielen weiteren Beispielen zum ESP32 Development Board) Spiel - Tic-Tac-Toe für das ESP32 Development BoardHerunterladen Im nachfolgenden YouTube-Video demonstriere ich dir das kleine Programm mit jeweils den 2 verschiedenen Möglichkeiten das der Spieler 0 oder X gewinnt und einmal unentschieden ist. https://youtu.be/-fHROLFvrhA Hier nun der Quellcode mit entsprechenden Kommentaren: /* Einbinden der Bibliothek zum kommunizieren mit dem Display. */ #define LGFX_USE_V1 #include #include "lgfx_ESP32_2432S028.h" //Größe der Zeichenfläche definieren #define MAX_X 319 #define MAX_Y 239 //Felder für die ermittelte Position //bei einem klick uint16_t x = 0, y = 0; //Instanz des Displays static LGFX lcd; //definieren eines Feldes struct Field { int32_t x; //X Koordinate int32_t y; //Y Koordinate bool isSelected; //bereits belegt? char symbol; //Symbol O oder X, default - }; //Spielfeld, 3x3 Felder groß Field playground = { { { 0, 0, false, '-' }, { 0, 0, false, '-' }, { 0, 0, false, '-' } }, { { 0, 0, false, '-' }, { 0, 0, false, '-' }, { 0, 0, false, '-' } }, { { 0, 0, false, '-' }, { 0, 0, false, '-' }, { 0, 0, false, '-' } } }; //Feld für den aktuellen Spieler bool currentPlayerX = true; //Feld ob das Spiel beendet ist bool gameOver = false; //Abmaße einer Spielfläche const int32_t DIMENSION = 50; //Abstände zwischen den Feldern const int32_t PADDING = 10; void setup(void) { //beginn der seriellen Kommunikation mit //115200 Baud Serial.begin(115200); //beginn der Kommunikation mit dem Display lcd.init(); //drehen des Displays lcd.setRotation(1); //füllen des Displays mit der Farbe Schwarz lcd.fillScreen(TFT_BLACK); //eine kleine Pause von 100ms. delay(100); //zeichnen des Hintergrundes inkl. dem befüllen //der Spielfläche mit den Koordinaten der Felder drawBackground(); } void loop() { //Wenn ein Touchaktion ausgeführt / erkannt wurde, //dann liefert die Funktion getTouch den Wert 1 und //befüllt die übergebenen Parametern mit den Koordinaten if (lcd.getTouch(&x, &y) == 1) { //Wenn die ermittelte X oder Y Positon außerhalb der Range ist, //dann soll die Funktion hier verlassen werden. if (x > MAX_X || y > MAX_Y) { return; } //Wenn das Spiel nicht beendet ist, dann... if (!gameOver) { //umkehren des Wertes des Feldes currentPlayerX //aus true wird false und andersherum currentPlayerX = !currentPlayerX; //Offset für das Symbol der Spieler int32_t offset = ((DIMENSION / 2) / 2) + 3; //For-Schleife über die Zeilen for (int row = 1; row < 4; row++) { //For-Schleife über die Spalten for (int col = 1; col < 4; col++) { //entnehmen eines Feldes aus dem Spielfeld Field& field = playground; //Wenn das Feld nicht belegt ist und die geklickte Koordinate //innerhalb dieses Feldes ist, dann... if (field.isSelected == false && checkCoord(field, x, y)) { //Feld als belegt markieren field.isSelected = true; //setzen der Schritgröße auf 4 lcd.setFont(&fonts::Font4); //Schriftfarbe setzen, //Schriftfarbe - schwarz, //Hintergrund - grau lcd.setTextColor(TFT_BLACK, TFT_LIGHTGREY); //Symbol setzen char symbol = currentPlayerX ? 'X' : 'O'; //platzieren des Cursors an die X/Y Koordinate mit offset lcd.setCursor(field.x + offset, field.y + offset); //schreiben des Symbols lcd.print(String(symbol)); //schreiben des Symbols auf das Feld field.symbol = symbol; //eine Pause von 250ms. delay(250); //prüfen ob das Spiel beendet ist, //zunächst wird geprüft ob der aktuelle Spieler gewonnen hat if (checkWin(symbol)) { //Anzeigen der Meldung das der Spieler gewonnen hat. showMessage("Spieler " + String(symbol) + " hat gewonnen!", 20); //Feld gameOver auf true setzen und damit wird im //nächsten Schritt der Else-Zweig betreten. gameOver = true; //eine Pause von 2 Sekunden. delay(2000); } else { //Wenn der aktuelle Spieler nicht gewonnen hat, dann wird geprüft //ob ggf. ein unentschieden besteht. //Im ersten Schritt wird geprüft ob noch Felder mit einem - existieren, //(alternativ könnte man auch das Feld isSelected wählen) bool playgroundContainsDash = false; for (int row = 1; row < 4; row++) { for (int col = 1; col < 4; col++) { Field& field = playground; if (field.symbol == '-') { playgroundContainsDash = true; } } } //Wenn alle Felder belegt sind, dann... if (!playgroundContainsDash) { //prüfen ob der Spieler O oder X gewonnen hat. //(Hier sollte eigentlich immer False als ergebnis kommen.) if (!checkWin('O') || !checkWin('X')) { //Anzeigen der Meldung "Unentschieden" showMessage("Unentschieden!", 55); //das Spiel beenden gameOver = true; } } } } } } } else { //Wenn das Spiel beendet ist, und der Spieler auf das Display klickt, //dann soll ein neues gestartet werden. gameOver = false; //das Array zurücksetzen initPlayground(); //zeichnen der Spielfläche drawBackground(); } } //eine Pause von 50ms. delay(50); } //Funktion zum zeichnen der Spielfläche void drawBackground() { // füllen des Displays mit der Farbe Schwarz lcd.fillScreen(TFT_BLACK); //Schriftgröße 4 lcd.setFont(&fonts::Font4); //Schriftfarbe setzen //Schriftfarbe - grau, //Hintergrundfarbe - schwarz lcd.setTextColor(TFT_LIGHTGREY, TFT_BLACK); //Text an der Koordinate schreiben lcd.drawString("Tic-Tac-Toe", 75, 25); //Zeichnen der Felder for (int row = 1; row < 4; row++) { for (int col = 1; col < 4; col++) { drawFilledRectangle(row, col); } } } //Zeichnet ein gefülltet Rechteck void drawFilledRectangle(int32_t row, int32_t col) { //berechnen der Position der Felder aus den Daten //Zeile & Spalte int32_t x = (DIMENSION + PADDING) * col; int32_t y = (DIMENSION + PADDING) * row; //Zeichnen des gefüllten Rechtecks lcd.fillRect(x, y, DIMENSION, DIMENSION, TFT_LIGHTGREY); //Speichern der Koordinaten an dem Feld Field& field = playground; field.x = x; field.y = y; } //Funktion zum prüfen ob die geklickte Koordinate innerhalb des Feldes liegt bool checkCoord(Field field, int x, int y) { return (x >= field.x && x = field.y && y Read the full article
0 notes
draegerit · 1 year ago
Text
ESP32 Development Board mit 2,8 Zoll Touch Display: Programmieren für Anfänger
Tumblr media
In diesem Beitrag möchte ich dir ein ESP32 Development Board mit Touch Display vorstellen und zeigen wie dieser programmiert wird. https://youtu.be/xEy-4FJiRHs Ein herzliches Dankeschön an lowstreaming für die großzügige Unterstützung mit dem ESP32 Mikrocontroller. Diese Geste ermöglicht mir, die spannenden Möglichkeiten des Mikrocontrollers und des 2,8 Zoll (ca. 7 cm) Touch Displays zu erkunden und gemeinsam Lösungen zu finden. Deine Unterstützung macht diese technologische Reise besonders inspirierend. Vielen Dank!
Tumblr media Tumblr media Tumblr media
Bezug
Diesen Mikrocontroller bekommst du auf ebay.de für derzeit knapp 18 €* inkl. Versandkosten. Auf alieexpress.com findest du dieses Modul unter "ESP32 Development Board 2.8inch LCD TFT" jedoch deutlich günstiger, jedoch musst du dort mit einer längeren Lieferzeit rechnen. Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Lieferumfang
Zum Lieferumfang gehört neben dem Mikrocontroller noch: - ein Micro-USB-Kabel, - ein Stift für den Touch Screen, - ein Anschlusskabel
Tumblr media
Pinout des ESP32 Development Board 2.8inch LCD TFT
Schauen wir uns zunächst den Aufbau des ESP32 Development Boards an. Auf der Vorderseite findest du das 2,8 Zoll TFT Touch Display. Auf der Rückseite wird es schon spannender, denn dort findest du einige Schnittstellen.
Tumblr media
Aufbau ESP32 Development Board mit 2,8 Zoll TFT Touch Display An den beiden seitlichen Schnittstellen kannst du zusätzliche Sensoren / Aktoren anschließen und programmieren. Des Weiteren findest du noch eine RGB LED, an welcher du die Farben separat via PWM Signal steuern kannst (es ist also keine WS18B20 LED oder ähnliches).
Tumblr media
Beschriftung der Schnittstellen und RGB LED am ESP32 Development Board
Technische Daten des ESP32 Development Board mit 2,8 Zoll Touch Display
ModellESP32-2432S028RProzessorESP32-WROOM-32(ESP32-D0WDQ6) Espressif ESP32 32 Bit Dual Core ProzessorBildschirmTFT Display mit ILI9341 Treiber, Auflösung: 240 px x 320 px, 2,8 Zoll (ca. 7 cm) TFT-Display, TouchscreenBetriebstemperatur -20 bis + 70 °CVersorgungsspannung5V, ca. 90 mAGewicht44 gModulgröße8,6 cm x 5,4 cm
Anschluss an den Computer und installieren des CH340 Treibers
Wenn du diesen Mikrocontroller an deinen Computer mit dem mitgelieferten Micro-USB-Kabel anschließt, dann sollte dieser sofort erkannt werden.
Tumblr media
Wenn dieser nicht erkannt wird, wie in der Grafik zu sehen, dann musst du den Treiber für den USB-Serial Converter CH340 installieren. Diesen Treiber kannst du dir unter https://www.wch.cn/download/CH341SER_ZIP.html herunterladen. Die Webseite ist leider auf Chinesisch, aber du kannst dir diese recht einfach im Browser mit wenigen Klicks übersetzen lassen.
Programmieren des ESP32 Development Board in der Arduino IDE
Zunächst möchte ich dieses Board in der Arduino IDE programmieren. Sämtlichen Quellcode von den Beispielen findest du auch auf meinem GitHub Repository unter StefanDraeger/ESP32_Development_Board_ESP32-2432S028R. Installieren des Boardtreibers für den ESP32 Dazu muss zunächst der Boardtreiber für den Mikrochip ESP-WROOM-32 installiert werden. Im ersten Schritt müssen wir wie erwähnt den Boardtreiber installieren, dazu navigieren wir zu den Einstellungen und wählen dort die Schaltfläche hinter "Zusätzliche Boardverwalter URLs"(1).
Tumblr media
Im neuen Dialog geben wir nun die nachfolgende Adresse(2) ein. https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json Und bestätigen dieses mit der Schaltfläche OK (3).
Tumblr media
Jetzt können wir zum Boardverwalter (4) wechseln und nach ESP32(5) suchen. Aus der Ergebnisliste wählen wir im Eintrag "esp32 von Espressif Systems" (6) die Schaltfläche INSTALLIEREN. In meinem Falle ist diese bereits in der derzeit aktuellen Version 2.014 installiert und ich habe hier die Schaltfläche ENTFERNEN (7).
Tumblr media
Programmieren der RGB LED Auf der Rückseite des ESP32 Development Boards findest du eine RGB LED, welche du über die nachfolgenden Pins via PWM Signal steuern kannst. - Rot > IO17 - Grün > IO4 - Blau > IO16 Beispiel - setzen einer Farbe an der RGB LED via PWM Signal Auf der Seite https://www.rapidtables.com/web/color/RGB_Color.html findest du einen einfachen ColorPicker aus welchem du dir eine Farbe auswählen und den RGB Wert ablesen kannst.
Tumblr media
Diesen RGB Wert (R = red, G = green, B = blue) setzt sich aus den Farben rot, grün und blau zusammen. Diese Farbe kannst du dann mit der Funktion "analogWrite(, )" setzen. //RGB LED //LED, Farbe rot #define ledRed 17 //LED, Farbe grün #define ledGreen 4 //LED, Farbe blau #define ledBlue 16 void setup() { //definieren das die Pins als Ausgang dienen pinMode(ledRed, OUTPUT); pinMode(ledGreen, OUTPUT); pinMode(ledBlue, OUTPUT); //setzen der Farbe lila an der RGB LED //Farbe rot mit 178 von max. 255 analogWrite(ledRed, 178); //Farbe grün mit 102 von max. 255 analogWrite(ledGreen, 102); //Farbe blau mit dem maximalen Wert von 255 analogWrite(ledBlue, 255); } void loop() { } Wenn der Quellcode nun übertragen wurde, dann sollte die RGB LED in der Farbe Lila aufleuchten.
Tumblr media
Programm - setzen der Farbe Lila an der RGB LED des ESP32 Development BoardHerunterladen Beispiel - anzeigen aller Farbkombinationen an der RGB LED Wir können jetzt mit drei For-Schleifen alle Farbkombinationen auf der RGB LED aufleuchten lassen. Dazu müssen wir lediglich in jeder Schleife den entsprechenden Farbwert setzen. //RGB LED //LED, Farbe rot #define ledRed 17 //LED, Farbe grün #define ledGreen 4 //LED, Farbe blau #define ledBlue 16 void setup() { //definieren das die Pins als Ausgang dienen pinMode(ledRed, OUTPUT); pinMode(ledGreen, OUTPUT); pinMode(ledBlue, OUTPUT); } void loop() { //For-Schleifen über die einzelnen Farbwerte for (int red = 0; red < 255; red++) { //setzen der Farbe rot mit dem aktuellen Wert aus der For-Schleife analogWrite(ledRed, red); for (int green = 0; green < 255; green++) { //setzen der Farbe grün mit dem aktuellen Wert aus der For-Schleife analogWrite(ledGreen, green); for (int blue = 0; blue < 255; blue++) { //setzen der Farbe blau mit dem aktuellen Wert aus der For-Schleife analogWrite(ledBlue, blue); //eine kleine Pause von 25 Millisekunden delay(25); } } } } TFT-Touchdisplay programmieren Als Nächstes möchte ich dir gerne zeigen, wie das TFT-Touchdisplay programmiert wird. Installieren der benötigten Bibliothek zum Ansteuern des TFT-Touchdisplays Bevor wir Text, Bilder oder geometrische Formen auf dem TFT-Display anzeigen können, müssen wir eine Bibliothek installieren. In der Arduino IDE öffnen wir dazu den Bibliotheksverwalter (1) und suchen dort nach "TFT_eSPI" (2), um diese Bibliothek jetzt zu installieren, müssen wir auf die Schaltfläche "INSTALLIEREN" klicken. In meinem Fall habe ich diese Bereits installiert und bei mir wird die Schaltfläche "ENTFERNEN" angezeigt.
Tumblr media
Diese Bibliothek kommt mit sehr vielen Beispielen daher, welche wir jedoch erst nach einer kleinen Änderung i lauffähig auf den Mikrocontroller aufspielen können. Konfiguration für das TFT-Display setzen Bevor wir jedoch mit dem TFT-Display arbeiten können, müssen wir die Konfiguration setzen, diese geben wir in der Datei "User_Setup.h" ein. Die Datei findest du im Ordner C:Users%username%DocumentsArduinolibrariesTFT_eSPI Es ist ratsam sich von der originalen Datei eine kopie zu erstellen so das man ggf. noch andere Displays später programmieren kann.
Tumblr media
Die nachfolgende Konfiguration habe ich vom GitHub Repository https://github.com/OttoMeister/ARDUINO_ESP32-2432S028R entnommen und funktioniert für den hier gezeigten Mikrocontroller. #define ILI9341_2_DRIVER #define TFT_WIDTH 240 #define TFT_HEIGHT 320 #define TFT_BL 21 #define TFT_BACKLIGHT_ON HIGH #define TFT_MOSI 13 #define TFT_SCLK 14 #define TFT_CS 15 #define TFT_DC 2 #define TFT_RST 12 #define TFT_BL 21 #define TOUCH_CS 33 #define LOAD_GLCD #define LOAD_FONT2 #define LOAD_FONT4 #define LOAD_FONT6 #define LOAD_FONT7 #define LOAD_FONT8 #define LOAD_GFXFF #define SMOOTH_FONT #define SPI_FREQUENCY 55000000 #define SPI_READ_FREQUENCY 20000000 //Touch Screen: ?????????ß #define XPT2046_IRQ 36 #define XPT2046_MOSI 32 #define XPT2046_MISO 39 #define XPT2046_CLK 25 #define XPT2046_CS 33 #define SPI_TOUCH_FREQUENCY 2500000 Beispiel - Text "Hallo Welt!" auf dem TFT-Display anzeigen Schreiben wir zunächst auf das TFT-Display den Text "Hallo Welt!" in unterschiedlicher Textgröße, Farbe und Position. //Bibliothek zum ansteuern des TFT Displays #include #include //Datei mit den definierten Schriftarten #include "Free_Fonts.h" //eine instanz vom TFT Display Objekt erstellen TFT_eSPI tft = TFT_eSPI(); void setup(void) { //beginn der kommunikation mit dem TFT Display tft.init(); //drehen des Displays tft.setRotation(3); //Hintergrundfarbe auf Schwarz setzen tft.fillScreen(TFT_BLACK); //Textfarbe Magenta mit Hintergrundfarbe Schwarz tft.setTextColor(TFT_MAGENTA, TFT_BLACK); //Schriftart FSB9 setzen tft.setFreeFont(FSB9); //den Cursor an die Position x=10 & y=45 setzen tft.setCursor(10, 45); //den Text "Hallo Welt!" an die gesetzte Cursorposition //schreiben tft.print("Hallo Welt!"); //Weitere Texte mit unterschiedlichen Farben, Positionen und //Schriftgrößen auf dem TFT-Display anzeigen tft.setTextColor(TFT_VIOLET, TFT_BLACK); tft.setFreeFont(FSB12); tft.setCursor(10, 65); tft.print("Hallo Welt!"); tft.setTextColor(TFT_PINK, TFT_BLACK); tft.setFreeFont(FSB18); tft.setCursor(10, 95); tft.print("Hallo Welt!"); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.setFreeFont(FSB24); tft.setCursor(10, 130); tft.print("Hallo Welt!"); } void loop() { } Der Code bewirkt nun das auf dem Display der Text "Hallo Welt!" in unterschiedlichen Textgrößen, Farben und Positionen angezeigt wird.
Tumblr media
Programm - schreiben von Text auf dem TFT-Display des ESP32 Development BoardHerunterladen Beispiel - Bild auf dem TFT-Display anzeigen Zur Bibliothek TFT_eSPI erhältst du wie erwähnt sehr viele Beispiele, eines davon ist "LittleFS_PNG". Dieses Beispiel demonstriert wie du ein Bild auf dem Display anzeigen lassen kannst. Einrichten eines LittleFS Dateisystems auf dem ESP32 Das LittleFS ist ein eigenes kleines, leichtgewichtiges Dateisystem welches auf Embeddedsystems wie dem ESP32 anwendung findet. Die Dateien werden dabei auf dem ESP32 Chip gespeichert und nicht auf der SD-Karte! Damit du Daten auf den Chip in diesem speziellen Format speichern kannst, benötigst du ein Plugin als JAR-Datei, jedoch kann du dieses nur in die klassische Arduino IDE (Version 1.8.x) integrieren.
Tumblr media
Ich habe mir nun die derzeitige Version 1.8.19 als ZIP-Datei heruntergeladen und entpackt. Im nächsten Schritt muss nun der Pfad wiefolgt angelegt werden arduino-1.8.19toolsESP32FStool und in diesen Ordner die Datei esp32fs.jar abgelegt werden.
Tumblr media
Ablegen von Dateien auf dem LittleFS Dateisystems In meinem Fall wechsel ich jetzt also nun von der neuen Arduino IDE 2.x zur klassischen Version um eine Datei auf den Mikrocontroller hochzuladen. Das Plugin findest du unter Werkzeuge > ESP32 Sketch Data Upload.
Tumblr media
Wenn nun auf den Menüeintrag "ESP32 Sketch Data Upload" geklickt wird, öffnet sich ein Dialog in welchem wir das Dateisystem auswählen.
Tumblr media Tumblr media
Im Ersten durchgang existiert der Ordner "data" im Sketch Ordner nicht und daher muss dieser zunächst angelegt werden. Daher bestätigen wir diesen Dialog mit der Schaltfläche "Yes". Wenn der Ordner und der Mikrocontroller vorbereitet wurden dann wird dir dieses in der Konsole mit dem Text "Hard resetting via RTC pin..." angezeigt.
Tumblr media Tumblr media
Wir können jetzt mit der Tastenkombination Strg + K oder über das Menü Sketch > Sketch-Ordner anzeigen in den Sketch Ordner wechsel und sollten nun einen zusätzlichen Ordner "data" sehen. Dieser Data liegt quasi paralell zur unserer INO-Datei. Read the full article
0 notes