Tetris am AZ-Touch - AZ-Delivery

Dieser Beitrag zeigt, wie Sie das bekannte Tetris Spiel mit einem Mikrocontroller und einem Touchscreen realisieren können. Als Basis wird das AZ-Touch Wandgehäuse mit 2.8 Zoll Display oder das AZ-Touch MOD Wandgehäuse mit 2.4 Zoll Display verwendet. Als Mikrocontroller kann ein ESP32 Dev-Kit C oder ein D1-Mini eingesetzt werden. Nachdem die Federleisten für Display und Controller auf der Bauteileseite eingelötet wurden, kann das Display montiert werden. Tipp: Nur die Federleisten (auch Caterpillar-Leisten genannt) einlöten, die für die jeweilige MCU benötigt werden.


Wenn der D1-Mini als Controller verwendet werden soll, sollte man diesen nicht mit den einfachen Stiftleisten bestücken, da die Stifte nicht sicher in der Fassung halten. Besser ist es den D1-Mini mit den kombinierten Feder-/Stiftleisten zu bestücken, da diese Stifte länger sind.


Wenn Sie die Caterpillar-Leisten für beide MCUs eingelötet haben, sollten die Pins der ESP32 Leiste, die unter dem D1-Mini liegen, mit einem Isolierband abgedeckt werden, damit es zu keiner leitenden Verbindung mit dem Gehäuse der USB-Buchse des D1-Minis kommt. Siehe Bild.

Benötigte Hardware

Anzahl

Bauteil

Anmerkung

1

AZ-Touch Wandgehäuse 2.8 Zoll Display

 

oder 1

AZ-Touch MOD Wandgehäuse 2.4 Zoll Display

 

1

ESP32 Dev C

 

oder 1

D1-Mini

 

 

Aufbau des Programms

Die Regeln für das Tetris-Spiel werden als bekannt vorausgesetzt. In dieser Implementation verwenden werden sieben verschiedene Teile verwendet. Mit den gedrehten Versionen ergibt das dann 19 unterschiedliche Teile.

Jedes Teil wird in einer Matrix mit 4 x 4 = 16 Bytes als Konstante gespeichert. Die sieben verschiedenen Teile erhalten unterschiedliche Farben. In der Matrix werden nicht belegte Blöcke mit 0, belegte Blöcke mit dem Index auf die Farbtabelle gefüllt.

//Farben für die Blöcke

const uint16_t colorBlock[8] = {ILI9341_BLACK, ILI9341_YELLOW, ILI9341_RED, ILI9341_CYAN, ILI9341_GREEN, ILI9341_PURPLE, ILI9341_BLUE, ILI9341_ORANGE};

 

//Bitmuster für die Teile

//0 = Block nicht gesetzt >0 Index der Farbe für den Block

const uint8_t piece[20][16] = {

  {0, 0, 0, 0, 

   0, 0, 0, 0,

   0, 0, 0, 0, 

   0, 0, 0, 0},

  {0, 0, 0, 0, 

   0, 0, 0, 0,

   1, 1, 0, 0, 

   1, 1, 0, 0},

  {0, 2, 0, 0,


Der Spielplan selbst hat 16 Zeilen mit 12 Spalten. Die Indizierung der Spalten ist von links nach rechts, die der Zeilen von unten nach oben.

Damit eine möglichst große Fläche für das Spiel zur Verfügung steht, werden keine Touch-Buttons angezeigt. Für den Start des Spieles dient eine Berührung des obersten Viertels des Bildschirms. Zum Bewegen der Teile dient das unterste Viertel des Bildschirms. Dieser Streifen ist gedrittelt. Eine Berührung des linken Drittels schiebt das herunterfallende Tetris-Teil nach links, eine Berührung des mittleren Drittels dreht das Teil und eine Berührung des rechten Drittels schiebt das Teil nach rechts.


Im Folgenden wird zum besseren Verständnis der Ablauf des Programms dargestellt. Ein Spiel wird gestartet, indem der Score und das Spielfeld gelöscht werden. Dann wird ein neues Teil ganz oben eingefügt. Das Spiel endet, wenn kein neues Teil eingefügt werden kann. Das Flussdiagramm zeigt den Ablauf der Hauptschleife.


Die Verschiebungen nach rechts und links sowie das Drehen, wird asynchron durch Touch Ereignisse ausgelöst. Nach einer Prüfung, ob die Änderung möglich ist, wird diese ausgeführt. Ist die Änderung nicht möglich, bleibt alles unverändert.

Bei jedem neu hinzugefügten Teil wird der Score um 4 erhöht. Wenn eine vollständige Zeile entfernt werden kann, wird der Score um 10 erhöht. Je nach Score werden der Level und die Fallgeschwindigkeit erhöht.

Score

Level

Fallgeschwindigkeit

<100

1

0.9 s/Zeile

<1000

2

0.7 s/Zeile

<10 000

3

0.5 s/Zeile

<100 000

4

0.3 s/Zeile

Ab 100 000

5

0.1 s/Zeile

 

Das Programm

Neben dem ESP32 oder ESP8266 Package werden folgende Bibliotheken benötigt:

  • Adafruit ILI9341
  • Adafruit GFX Library
  • XPT2046_Touchscreen
  • TouchEvent

Das Programm unterscheidet automatisch zwischen ESP32 und D1-Mini und verwendet die entsprechenden Pinbelegungen. Die vorliegende Version ist für das 2.8 Zoll Display. Für das 2.4 Zoll Display muss die Zeile
#define TOUCH_ROTATION = 3
auf
#define TOUCH_ROTATION = 1
geändert werden.

 

#include <Adafruit_GFX.h> //Grafik Bibliothek
#include <Adafruit_ILI9341.h> // Display Treiber
#include <XPT2046_Touchscreen.h> //Touchscreen Treiber
#include <TouchEvent.h> //Auswertung von Touchscreen Ereignissen

//Aussehen
#define BACKGROUND ILI9341_GREENYELLOW //Farbe des Rahmens
#define TOPMARGIN 20                   //Rand oben
#define LEFTMARGIN 12                  //Rand links und rechts
#define COLUMNS 12                     //Anzahl der Spalten
#define ROWS 16                        //Anzahl der Zeilen
#define BLOCKSIZE 18                   //Größe eines Blocks in Pixel
#define NOPIECE ILI9341_BLACK          //Farb für das leere Spielfeld 
#define ALLON ILI9341_DARKGREY         //Farbe für alle Blöcke ein
#define BORDER ILI9341_WHITE           //Farbe für den Blockrand

//Unterschiedliche Pin-Belegung für ESP32 und D1Mini
#ifdef ESP32
  #define TFT_CS   5   
  #define TFT_DC   4   
  #define TFT_RST  22
  #define TFT_LED  15
  #define TOUCH_CS 14
  #define LED_ON 0
#endif
#ifdef ESP8266
  #define TFT_CS   D1   
  #define TFT_DC   D2  
  #define TFT_RST  -1
  #define TFT_LED  D8
  #define TOUCH_CS 0
  #define LED_ON 1
#endif

#define TOUCH_ROTATION 3 //muss für 2.4 Zoll Display 1 und für 2.8 Zoll Display 3 sein
//Instanzen der Bibliotheken
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen touch(TOUCH_CS);
TouchEvent tevent(touch);

//Farben für die Blöcke
const uint16_t colorBlock[8] = {ILI9341_BLACK, ILI9341_YELLOW, ILI9341_RED, ILI9341_CYAN, ILI9341_GREEN, ILI9341_PURPLE, ILI9341_BLUE, ILI9341_ORANGE};

//Bitmuster für die Teile
//0 = Block nicht gesetzt >0 Index der Farbe für den Block
const uint8_t piece[20][16] = {
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   0, 0, 0, 0,  
   0, 0, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   1, 1, 0, 0,  
   1, 1, 0, 0},
  {0, 2, 0, 0, 
   0, 2, 0, 0,
   0, 2, 0, 0, 
   0, 2, 0, 0},
  {0, 0, 0, 0, 
   0, 0, 0, 0,
   0, 0, 0, 0, 
   2, 2, 2, 2},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   3, 3, 0, 0,  
   0, 3, 3, 0},
  {0, 0, 0, 0,  
   0, 3, 0, 0, 
   3, 3, 0, 0,  
   3, 0, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   0, 4, 4, 0,  
   4, 4, 0, 0},
  {0, 0, 0, 0,  
   4, 0, 0, 0, 
   4, 4, 0, 0,  
   0, 4, 0, 0},
  {0, 0, 0, 0,  
   5, 0, 0, 0, 
   5, 0, 0, 0,  
   5, 5, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   0, 0, 5, 0,  
   5, 5, 5, 0},
  {0, 0, 0, 0,  
   5, 5, 0, 0, 
   0, 5, 0, 0,  
   0, 5, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   5, 5, 5, 0,  
   5, 0, 0, 0},
  {0, 0, 0, 0,  
   0, 6, 0, 0, 
   0, 6, 0, 0,  
   6, 6, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   6, 6, 6, 0,  
   0, 0, 6, 0},
  {0, 0, 0, 0,  
   6, 6, 0, 0, 
   6, 0, 0, 0,  
   6, 0, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   6, 0, 0, 0,  
   6, 6, 6, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   0, 7, 0, 0,  
   7, 7, 7, 0},
  {0, 0, 0, 0,  
   0, 7, 0, 0, 
   7, 7, 0, 0,  
   0, 7, 0, 0},
  {0, 0, 0, 0,  
   0, 0, 0, 0, 
   7, 7, 7, 0,  
   0, 7, 0, 0},
  {0, 0, 0, 0,  
   0, 7, 0, 0, 
   0, 7, 7, 0,  
   0, 7, 0, 0}
};

//Speicherplatz für das Spielfeld
//0 bedeutet Block frei >0 Index der Farbe des belegten Blocks
uint8_t playGround[ROWS][COLUMNS]; 

//Globale variablen
uint8_t curPiece;  //aktuelles Tetris Teil
int8_t curCol;     //aktuelle Spalte
int8_t curRow;     //aktuelle Zeile
uint32_t score;    //aktueller Score
uint8_t level;     //aktueller Level
uint16_t interval; //aktuelles Zeitintervall für die Abwärtsbewegung

uint32_t last;     //letzter Zeitstempel


//Fuktion zeigt in der Kopfleiste den aktuellen Score und den Level an
//Abhängig vom Score wird der Level hinaufgesetzt und das Intervall verringert
void displayScore() {
  if (score < 10) {level = 1; interval = 900;}
  else if (score < 100) {level = 2; interval = 700;}
  else if (score < 1000) {level = 3; interval = 500;}
  else if (score < 10000) {level = 4; interval = 300;}
  else if (score < 100000) {level = 5; interval = 100;}
  tft.fillRect(0,0,240,20,BACKGROUND);
  tft.setTextSize(2);
  tft.setTextColor(ILI9341_BLACK);
  tft.setCursor(5,4);
  char buf[50];
  sprintf(buf,"SC: %8i LV: %i",score,level);
  tft.print(buf);
}

//Funktion um ein Tetris-Teil zu drehen. Der Parameter ist die Nummer des
//Teils das gedreht werden soll. Rückgabewert ist der Index des vgerehten
//Teils
uint8_t rotate(uint8_t pc) {
  uint8_t res = 0;
  switch (pc) {
    case 1: res = 1; break;
    case 2: res = 3; break;
    case 3: res = 2; break;
    case 4: res = 5; break;
    case 5: res = 4; break;
    case 6: res = 7; break;
    case 7: res = 6; break;
    case 8: res = 9; break;
    case 9: res = 10; break;
    case 10: res = 11; break;
    case 11: res = 8; break;
    case 12: res = 13; break;
    case 13: res = 14; break;
    case 14: res = 15; break;
    case 15: res = 12; break;
    case 16: res = 17; break;
    case 17: res = 18; break;
    case 18: res = 19; break;
    case 19: res = 16; break;
  }
  return res;
}

//Funktion testet ob eine Zeile voll belegt ist
boolean rowComplete(int8_t rpg) {
  if ((rpg >= 0) && (rpg < ROWS)) {
    boolean res = true;
    uint8_t c = 0;
    //wenn ein Block nicht belegt ist (Farbe 0),
    //ist die Zeile nicht vollständig
    while (res && (c < COLUMNS)) {
      if (playGround[rpg][c] == 0) res = false;
      c++;
    }
    return res;
  }
}

//Funkzion prüft ob es zwischen der Zeile rpc des Tetris-Teils pc und
//der Zeile rpg des Spielfelds ab der Position cpg Kolklisionen gibt.
//Wenn eine Kollision auftritt oder die letzte Zeile des Spielfelds 
//erreicht wurde wird falsch zurückgegeben
boolean checkRow(uint8_t pc, int8_t rpc, int8_t cpg, int8_t rpg) {
  boolean res = true;
  if (rpg >= ROWS) return false;
  if (rpg < 0) return true;
  for (uint8_t i = 0; i<4; i++) {
    if (piece[pc][rpc*4 + i]>0) {
      if (((cpg+i) < 0) || ((cpg+i) >= COLUMNS)) {
        res = false;
      }else {
        if (playGround[rpg][cpg+i] > 0) res = false;
      }
    }
  }
  return res;
}

//Funktion prüft ob das Tetris Teil pc am Spielfeld an der Position 
//Zeile rpg Spalte cpg (linke untere Ecke des Teils) Kollisionen auftreten
boolean checkPiece(uint8_t pc, int8_t cpg, int8_t rpg) {
  boolean res = true;
  uint8_t rpc = 0;
  while (res && (rpc < 4)) {
    res = checkRow(pc,rpc,cpg,rpc+rpg-3);
//    Serial.printf("check %i = %i\n",rpc+rpg-3,res);
    rpc++;
  }
  return res;
}

//Funktion zeigt einen Block des Spielfeldes in Zeile y Spalte x mit der Farbe color an
//color ist die Farbe im 565 Format für das Display
void showBlock(uint8_t x, uint8_t y, uint16_t color) {
  tft.fillRect(LEFTMARGIN+x*BLOCKSIZE+2,TOPMARGIN+y*BLOCKSIZE+2,BLOCKSIZE-4,BLOCKSIZE-4,color);
  tft.drawRect(LEFTMARGIN+x*BLOCKSIZE+1,TOPMARGIN+y*BLOCKSIZE+1,BLOCKSIZE-2,BLOCKSIZE-2,BORDER);
}

//Funktion füllt einen Block des Spielfeldes in Zeile y Spalte x mit der Hintergrundfarbe
void hideBlock(uint8_t x, uint8_t y) {
  tft.fillRect(LEFTMARGIN+x*BLOCKSIZE,TOPMARGIN+y*BLOCKSIZE,BLOCKSIZE,BLOCKSIZE,NOPIECE);
}

//Funktion zeigt das Tetris-Teil pc in Zeile rpg, Spalte cpg (Linke untere Ecke) an
//Die Farbe wird der Definition des Tetris-Teils entnommen
void showPiece(uint8_t pc, uint8_t cpg, uint8_t rpg) {
  uint8_t color;
  for (uint8_t r = 0; r<4; r++)  {
    for (uint8_t c = 0; c<4; c++) {
      color = piece[pc][r*4+c];
      if ((color > 0) && ((3-r+rpg) >= 0)) showBlock(cpg+c,rpg-3+r,colorBlock[color]);
    }
  }
}

//Funktion füllt die belegten Blöcke des Tetris-Teil pc in Zeile rpg, 
//Spalte cpg (Linke untere Ecke) an mit Hintergrundfarbe
void hidePiece(uint8_t pc, int8_t cpg, int8_t rpg) {
  uint8_t color;
  for (uint8_t r = 0; r<4; r++)  {
    for (uint8_t c = 0; c<4; c++) {
      color = piece[pc][r*4+c];
      if ((color > 0) && ((3-r+rpg) >= 0)) hideBlock(cpg+c,rpg-3+r);
    }
  }
}

//funktion füllt die Zeile row des Spielfelds mit Hintergrundfarbe und 
//löscht alle Einträge für diese Zeile im Spielfeld-Speicher
void deleteRow(int8_t row) {
  tft.fillRect(LEFTMARGIN,TOPMARGIN+row*BLOCKSIZE,COLUMNS * BLOCKSIZE,BLOCKSIZE,NOPIECE);
  for (uint8_t i =0; i<COLUMNS; i++) playGround[row][i]=0;
}

//Funktion kopiert die Zeile srcrow in die Zeile dstrow
//Die Anzeige der Zielzeile wird vorher gelöscht. Beim
//kopieren wird die Quellzeile in der Zielzeile angezeigt
void copyRow(int8_t srcrow, int8_t dstrow) {
  uint8_t col;
  deleteRow(dstrow);
  if ((srcrow < dstrow) && (srcrow >=0) && (dstrow < ROWS)) {
    for (uint8_t c = 0; c < COLUMNS; c++) {
      col = playGround[srcrow][c];
      playGround[dstrow][c] = col;
      if (col > 0) showBlock(c,dstrow,colorBlock[col]);
    }
  }
}

//Funktion zeigt alle Blöcke des Spielfeldes mit der Farbe ALLON an.
//Nach einer Pause von 500 ms wird das Sielfeld komplett gelöscht
void clearBoard() {
  for (uint8_t x = 0; x<COLUMNS; x++) {
    for (uint8_t y = 0; y<ROWS; y++) {
      showBlock(x,y,ALLON);
    }
  }
  delay(500);
  for (uint8_t i = 0; i<ROWS; i++) {
    deleteRow(i);
  }
}

//Funktion überträgt das Tetris-Teil pc in den Spielfeldspeicher in der Zeile 
//rpg an der Spalte cpg (linke untere Ecke)
void putPiece(uint8_t pc, int8_t cpg, int8_t rpg) {
  uint8_t color;
  for (uint8_t r = 0; r<4; r++)  {
    for (uint8_t c = 0; c<4; c++) {
      color = piece[pc][r*4+c];
      if ((color > 0) && ((3-r+rpg) >= 0)) playGround[rpg-3+r][cpg+c] = color;
    }
  }
}

//Ein neues Tetristeil wird am oberen Rand des Spielfeldes eingefügt.
//Welches Teil und in welcher Spalte wird als Zufallszahl ermittelt
//Hat das neue Teil keinen Platz am Spielfeld, so ist das Spiel zu Ende
boolean newPiece() {
  uint8_t pc = random(1,20);
  uint8_t cpg = random(0,COLUMNS-4);
  boolean res = checkPiece(pc,cpg,3);
  curPiece=0;
  if (res) {
    curPiece = pc;
    curCol = cpg;
    curRow = 0;
    showPiece(pc,cpg,0);
    score += 4;
    displayScore();
  } else {
    tft.setTextSize(3);
    tft.setCursor(LEFTMARGIN+COLUMNS*BLOCKSIZE/2-79,TOPMARGIN+ROWS*BLOCKSIZE/2-10);
    tft.setTextColor(ILI9341_BLACK);
    tft.print("GAME OVER");
    tft.setCursor(LEFTMARGIN+COLUMNS*BLOCKSIZE/2-81,TOPMARGIN+ROWS*BLOCKSIZE/2-12);
    tft.setTextColor(ILI9341_YELLOW);
    tft.print("GAME OVER");
  }
}

//Funktion ermittelt komplett gefüllte Zeilen am Spielfeld und entfernt diese
//Darüberliegende Zeilen werden nach unten verschoben
void removeComplete() {
  uint8_t s=ROWS-1;
  int8_t d= ROWS-1; 
  while (d >= 0) {
    if (rowComplete(d)) {
      s--;
      score += 10;
      copyRow(s,d);
    } else {
      if ((s < d) && (s >=0)) {
        Serial.printf("copy %i to %i\n",s, d);
        copyRow(s,d);
      }
      s--;
      d--;
    }
  }
 displayScore();
}

//Funktion beginnt ein neues Spiel. Der score wird auf 0 gesetzt, das Spielfeld
//gelöscht und mit einem neuen Tetris Teil gestartet
void newGame() {
  score=0;
  displayScore();
  clearBoard();
  newPiece();
}

//Callbackfunktion für Touchscreen Ereignis Klick
//Diese Funktion wird immer dann aufgerufen, wenn der Bildschirm
//kurz berührt wird. p gibt die Position des Berührungspunktes an
void onClick(TS_Point p) {
  
  if (p.y < 80) { //Klick im obersten Viertel des Displays
    newGame();
  } else if (p.y > 240) { //Klick im untersten Viertel 
    uint8_t pc = curPiece;
    int8_t c = curCol;
    if (p.x < 80) { //Klick im linken Drittel -> nach links schieben
      c--;
    } else if (p.x <160) { //Klick im mittleren Drittel -> drehen
      pc = rotate(pc);
    } else { //Klick im rechten Drittel -> nach rechts schieben
      c++;
    }
    //nach Änderung der Position wird auf Kollision geprüft
    //nur wenn keine Kollision auftritt, wird die Bewegung
    //ausgeführt
    if (checkPiece(pc,c,curRow)) {
      hidePiece(curPiece,curCol,curRow);
      curPiece = pc;
      curCol = c;
      showPiece(curPiece,curCol,curRow);
    } 
  }
}

//Vorbereitung
void setup() {
  Serial.begin(115200);
  //Hintergrundbeleuchtung einschalten
  pinMode(TFT_LED,OUTPUT);
  digitalWrite(TFT_LED, LED_ON);
  Serial.println("Start");
  //Display initialisieren
  tft.begin();
  tft.fillScreen(BACKGROUND);
  //Touchscreen vorbereiten
  touch.begin();
  touch.setRotation(TOUCH_ROTATION);
  tevent.setResolution(tft.width(),tft.height());
  tevent.setDrawMode(false);
  //Callback Funktion registrieren
  tevent.registerOnTouchClick(onClick);
  //tft.fillRect(LEFTMARGIN,TOPMARGIN,COLUMNS*BLOCKSIZE,ROWS*BLOCKSIZE,NOPIECE);
  clearBoard();
  //newPiece();
  //Startzeit merken und Spielfeld löschen
  last = millis(); 
  score=0;
  displayScore();
}

//Hauptschleife
void loop() {
  //Auf Touch Ereignisse prüfen
  tevent.pollTouchScreen();
  //Immer wenn die Zeit intterval erreicht ist, wird das aktuelle Tetris-Teil
  //um eine Zeile nach unten geschoben falls das möglich ist.
  //Kommt es dabei zu einer Kollision oder wird der untere Rand erreicht, 
  //so wird das Teil nicht verschoben sondern am Spielfeld verankert.
  //Vollständige Zeilen werden entfernt und ein neues Teil am oberen
  //Rand eingefügt
  if ((curPiece > 0) && ((millis()-last) > interval)) {
    last = millis();
    if (checkPiece(curPiece,curCol,curRow+1)) {
      hidePiece(curPiece,curCol,curRow);
      curRow++;
      showPiece(curPiece,curCol,curRow);
    } else {
      putPiece(curPiece,curCol,curRow);
      removeComplete();
      newPiece();
    }
  }
}

 

Sketch zum herunterladen

Beitrag als PDF

Viel Spaß beim Spielen.

 

DisplaysEsp-32Esp-8266Smart home

4 comments

Bernhard

Bernhard

Bei mir hat das Übertragen problemlos funktioniert. Display + Touch funktionieren. Wenn ich allerdings das Spiel starte kommt es zu einer Exception/Reboot. Ich kann keinen Fehler finden – weder in Code noch in meinem Setup :-(
Woran könnte es liegen?
ArduinoTouch 01-03 mit ESP8266, 2.4Zoll TFT

Gerald

Gerald

Hallo TimQ,
die meisten Beispiele auch die im Smarthome-Buch arbeiten mit der AZ-Touch Version mit 2.4 Zoll Display und der alten Version der Platine, bei der ein Jumper zum Hochladen angeschlossen werden musste. Bei der neuen Platine wurde die Interruptleitung für den Touchscreen auf Pin27 geändert. Hier die notwendigen Änderungen damit die Smarthome-Zentrale aus dem Smarthome Buch funktioniert.

Das neue AZ-Touch MOD hat den Interrupt für den Touchscreen nicht mehr an Pin 2 sondern an Pin27.
Die entsprechende Definition am Anfang der Smarthome Sketches muss daher
#define TOUCH_IRQ 27
lauten.
Bei der Verwendung des 2.8 Zoll Displays muss außerdem in der Setup-Funktion nach
touch.begin();
touch.setRotation(3);
eingefügt werden.

Birger T

Birger T

Dieses Projekt sollte der Beginn meiner Beschäftigung mit den ESP32 und ESP8266 aus einem AZ-Delivery Überraschungspaket sein. Nach dem Studium der diversen E-books habe ich auch irgendwo den Hinweis gefunden, wie weitere Bordverwalter URLs in die Arduino IDE zu ergänzen sind und somit die “Boards” installiert werden können. Doch der erste Versuch mit dem Blink-Sketch funktionierte nicht: Kompilierung abgebrochen, weil das im ESP-Tool einzubindende “Serial” nicht vorhanden ist.
Ich arbeite unter Ubuntu 20.04 – und wollte hier denjenigen Ubuntu Usern, die ebenfalls Probleme mit der ESP Programmierung in der Arduino IDE das Problem mit dem “Serial” haben, einen/den Link zur Lösung mitteilen: https://koen.vervloesem.eu/blog/fixing-the-arduino-ide-for-the-esp32esp8266-on-ubuntu-2004/

TimQ

TimQ

Das ist das erste Beispiel für den AZ-Touch MOD 01-03 und ESP32, das funktioniert. Super !
Alle anderen Versuche mit den Beispielen aus den Blocks, Smarthome Buch oder den zahlreichen Foren sind bei mir gescheitert. Entweder blieb der Screen weiß oder dunkel. Ich hoffe es gibt bald mal eine wirklich funktionierende Beschreibung zur Smarthome Zentrale. Danke

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery