Hallo Leute, ich bin ganz neu hier, und brauche dringend eure Hilfe.
Es geht darum, ich habe einen Arduino Mega auf einem Elegoo Board. Außerdem habe ich zwei 4“ TFT Displays mit Touchfunktion: (amazon link zum Display) https://amzn.eu/d/00GzBOz8
Ich möchte gerne, dass die Displays zwar das selbe anzeigen, aber auch über beide Touchscreens bedienbar sind. Also, wenn zum Beispiel am ersten Display etwas gedrückt wird, dass es dann auf beiden Displays aktualisiert wird.
Beziehungsweise im weiteren dann auch die Displays zwei verschiedene Sachen anzeigen aber soweit bin ich noch nicht.
Hier mein Code, das Problem ist, dass zwar beide Displays richtig anzeigen, aber nur ein Touch geht und ich komm einfach nicht auf den Fehler. Ich habe auch ein paar serielle Ausgaben hinzugefügt, damit ich sehe, ob der zweite Touchscreen überhaupt erkannt wird, aber das tut er nicht, Nur der erste.
Danke beste Grüße
#include <Adafruit_GFX.h>
#include <Adafruit_ST7796S_kbv.h>
#include <XPT2046_Touchscreen.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans18pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
#include <Arduino.h>
// Pins für das erste Display (Hardware-SPI)
#define TFT_CS1 10
#define TFT_RST1 8
#define TFT_DC1 9
// Pins für das zweite Display (Hardware-SPI)
#define TFT_CS2 11
#define TFT_RST2 7
#define TFT_DC2 6
// Pins für den ersten Touchscreen (Hardware-SPI)
#define TOUCH_CS1 4
#define TOUCH_IRQ1 2
// Pins für den zweiten Touchscreen (Hardware-SPI)
#define TOUCH_CS2 5
#define TOUCH_IRQ2 3
Adafruit_ST7796S_kbv tft1 = Adafruit_ST7796S_kbv(TFT_CS1, TFT_DC1, TFT_RST1);
XPT2046_Touchscreen ts1(TOUCH_CS1, TOUCH_IRQ1);
Adafruit_ST7796S_kbv tft2 = Adafruit_ST7796S_kbv(TFT_CS2, TFT_DC2, TFT_RST2);
XPT2046_Touchscreen ts2(TOUCH_CS2, TOUCH_IRQ2);
int rectWidth = 200;
int rectHeight = 100;
int rectX;
int rectY;
bool initialScreen = true;
bool gameScreen = false;
unsigned long gameStartTime;
int gameTime = 30; // Zeit für das Spiel in Sekunden
int hits = 0;
void drawInitialButton() {
tft1.fillScreen(ST7796S_BLACK); // Bildschirm löschen
tft1.fillRect(rectX, rectY, rectWidth, rectHeight, ST7796S_RED);
tft1.setFont(&FreeSans18pt7b);
int16_t x1, y1;
uint16_t w, h;
tft1.getTextBounds("Test starten", 0, 0, &x1, &y1, &w, &h);
int16_t textX = rectX + (rectWidth - w) / 2;
int16_t textY = rectY + (rectHeight + h) / 2;
tft1.setCursor(textX, textY);
tft1.setTextColor(ST7796S_BLUE);
tft1.print("Test starten");
tft2.fillScreen(ST7796S_BLACK); // Bildschirm löschen
tft2.fillRect(rectX, rectY, rectWidth, rectHeight, ST7796S_RED);
tft2.setFont(&FreeSans18pt7b);
tft2.setCursor(textX, textY);
tft2.setTextColor(ST7796S_BLUE);
tft2.print("Test starten");
}
void drawOverlay() {
tft1.fillScreen(ST7796S_BLACK);
tft2.fillScreen(ST7796S_BLACK);
// Einzelspieler-Button
int singlePlayerButtonX = 50;
int singlePlayerButtonY = 100;
tft1.fillRect(singlePlayerButtonX, singlePlayerButtonY, 150, 50, ST7796S_RED);
tft1.setCursor(singlePlayerButtonX + 10, singlePlayerButtonY + 30);
tft1.setTextColor(ST7796S_WHITE);
tft1.setFont(&FreeSans9pt7b);
tft1.print("Einzelspieler");
tft2.fillRect(singlePlayerButtonX, singlePlayerButtonY, 150, 50, ST7796S_RED);
tft2.setCursor(singlePlayerButtonX + 10, singlePlayerButtonY + 30);
tft2.setTextColor(ST7796S_WHITE);
tft2.setFont(&FreeSans9pt7b);
tft2.print("Einzelspieler");
// Mehrspieler-Button
int multiPlayerButtonX = tft1.width() - 200;
int multiPlayerButtonY = 100;
tft1.fillRect(multiPlayerButtonX, multiPlayerButtonY, 150, 50, ST7796S_GREEN);
tft1.setCursor(multiPlayerButtonX + 10, multiPlayerButtonY + 30);
tft1.setTextColor(ST7796S_WHITE);
tft1.print("Mehrspieler");
tft2.fillRect(multiPlayerButtonX, multiPlayerButtonY, 150, 50, ST7796S_GREEN);
tft2.setCursor(multiPlayerButtonX + 10, multiPlayerButtonY + 30);
tft2.setTextColor(ST7796S_WHITE);
tft2.print("Mehrspieler");
// Beenden-Button
int endButtonX = (tft1.width() - 100) / 2;
int endButtonY = tft1.height() - 60;
tft1.fillRect(endButtonX, endButtonY, 100, 50, ST7796S_BLUE);
tft1.setCursor(endButtonX + 20, endButtonY + 30);
tft1.setTextColor(ST7796S_WHITE);
tft1.print("Beenden");
tft2.fillRect(endButtonX, endButtonY, 100, 50, ST7796S_BLUE);
tft2.setCursor(endButtonX + 20, endButtonY + 30);
tft2.setTextColor(ST7796S_WHITE);
tft2.print("Beenden");
}
void drawGameScreen(int timeLeft, int hits) {
// Timer oben
tft1.setFont(&FreeSans9pt7b);
tft1.fillRect(20, 20, 100, 30, ST7796S_BLACK); // Lösche alten Timer
tft1.setCursor(20, 30);
tft1.setTextColor(ST7796S_WHITE);
tft1.print("Timer: ");
tft1.print(timeLeft);
tft2.setFont(&FreeSans9pt7b);
tft2.fillRect(20, 20, 100, 30, ST7796S_BLACK); // Lösche alten Timer
tft2.setCursor(20, 30);
tft2.setTextColor(ST7796S_WHITE);
tft2.print("Timer: ");
tft2.print(timeLeft);
// Treffer in der Mitte
tft1.fillRect((tft1.width() - 150) / 2, (tft1.height() / 2) - 20, 150, 40, ST7796S_BLACK); // Lösche alten Treffertext
tft1.setCursor((tft1.width() - 150) / 2, tft1.height() / 2);
tft1.setTextColor(ST7796S_WHITE);
tft1.setFont(&FreeSans24pt7b);
tft1.print("Treffer: ");
tft1.print(hits);
tft2.fillRect((tft2.width() - 150) / 2, (tft2.height() / 2) - 20, 150, 40, ST7796S_BLACK); // Lösche alten Treffertext
tft2.setCursor((tft2.width() - 150) / 2, tft2.height() / 2);
tft2.setTextColor(ST7796S_WHITE);
tft2.setFont(&FreeSans24pt7b);
tft2.print("Treffer: ");
tft2.print(hits);
}
void drawStopButton() {
// Stop-Button unten
int stopButtonX = (tft1.width() - 100) / 2;
int stopButtonY = tft1.height() - 60;
tft1.fillRect(stopButtonX, stopButtonY, 100, 50, ST7796S_RED);
tft1.setCursor(stopButtonX + 20, stopButtonY + 30);
tft1.setTextColor(ST7796S_WHITE);
tft1.setFont(&FreeSans9pt7b);
tft1.print("Stop");
tft2.fillRect(stopButtonX, stopButtonY, 100, 50, ST7796S_RED);
tft2.setCursor(stopButtonX + 20, stopButtonY + 30);
tft2.setTextColor(ST7796S_WHITE);
tft2.setFont(&FreeSans9pt7b);
tft2.print("Stop");
}
void startCountdown(int seconds) {
for (int i = seconds; i > 0; i--) {
tft1.fillScreen(ST7796S_BLACK);
tft1.setFont(&FreeSans24pt7b);
tft1.setCursor((tft1.width() - 50) / 2, (tft1.height() - 50) / 2);
switch (i) {
case 3:
tft1.setTextColor(ST7796S_RED);
break;
case 2:
tft1.setTextColor(ST7796S_YELLOW);
break;
case 1:
tft1.setTextColor(ST7796S_GREEN);
break;
}
tft1.print(i);
tft2.fillScreen(ST7796S_BLACK);
tft2.setFont(&FreeSans24pt7b);
tft2.setCursor((tft2.width() - 50) / 2, (tft2.height() - 50) / 2);
switch (i) {
case 3:
tft2.setTextColor(ST7796S_RED);
break;
case 2:
tft2.setTextColor(ST7796S_YELLOW);
break;
case 1:
tft2.setTextColor(ST7796S_GREEN);
break;
}
tft2.print(i);
delay(1000);
}
// Zeige “Start” an
tft1.fillScreen(ST7796S_BLACK);
tft1.setFont(&FreeSans24pt7b);
tft1.setCursor((tft1.width() - 100) / 2, (tft1.height() - 50) / 2);
tft1.setTextColor(ST7796S_WHITE);
tft1.print("Start");
tft2.fillScreen(ST7796S_BLACK);
tft2.setFont(&FreeSans24pt7b);
tft2.setCursor((tft2.width() - 100) / 2, (tft2.height() - 50) / 2);
tft2.setTextColor(ST7796S_WHITE);
tft2.print("Start");
delay(1000);
// Bildschirm nach Countdown löschen
tft1.fillScreen(ST7796S_BLACK);
tft2.fillScreen(ST7796S_BLACK);
}
void handleTouch(XPT2046_Touchscreen &ts, Adafruit_ST7796S_kbv &tft, const char* displayName) {
if (ts.touched()) {
// Holen Sie sich die Touch-Informationen
TS_Point p = ts.getPoint();
// Anpassung der Bereichswerte basierend auf der Rohwert-Ausgabe
int mapX = map(p.x, 300, 3900, 0, 480);
int mapY = map(p.y, 300, 3900, 0, 320);
// Anpassung der Koordinaten für die doppelte Spiegelung
mapX = 480 - mapX;
mapY = 320 - mapY;
Serial.print(displayName);
Serial.print(" Touch detected! Mapped X = ");
Serial.print(mapX);
Serial.print(" Mapped Y = ");
Serial.println(mapY);
if (initialScreen) {
// Überprüfen, ob der Touch innerhalb des Rechtecks liegt
if (mapX >= rectX && mapX <= (rectX + rectWidth) && mapY >= rectY && mapY <= (rectY + rectHeight)) {
// Zeichne das Overlay
drawOverlay();
// Setze initialScreen auf false
initialScreen = false;
}
} else if (gameScreen) {
// Überprüfen, ob der Stop-Button gedrückt wird
int stopButtonX = (tft.width() - 100) / 2;
int stopButtonY = tft.height() - 60;
if (mapX >= stopButtonX && mapX <= (stopButtonX + 100) && mapY >= stopButtonY && mapY <= (stopButtonY + 50)) {
// Zeichne den initialen Button
drawInitialButton();
// Setze initialScreen auf true
initialScreen = true;
gameScreen = false;
}
} else {
// Überprüfen, ob einer der neuen Buttons gedrückt wird
int singlePlayerButtonX = 50;
int singlePlayerButtonY = 100;
int multiPlayerButtonX = tft.width() - 200;
int multiPlayerButtonY = 100;
int endButtonX = (tft.width() - 100) / 2;
int endButtonY = tft.height() - 60;
if (mapX >= singlePlayerButtonX && mapX <= (singlePlayerButtonX + 150) && mapY >= singlePlayerButtonY && mapY <= (singlePlayerButtonY + 50)) {
// 3-Sekunden Countdown starten
startCountdown(3);
// Zeichne das Spielinterface
gameStartTime = millis();
hits = 0;
drawGameScreen(gameTime, hits);
drawStopButton();
// Setze gameScreen auf true
gameScreen = true;
}
if (mapX >= multiPlayerButtonX && mapX <= (multiPlayerButtonX + 150) && mapY >= multiPlayerButtonY && mapY <= (multiPlayerButtonY + 50)) {
// Aktion für Mehrspieler-Button
}
if (mapX >= endButtonX && mapX <= (endButtonX + 100) && mapY >= endButtonY && mapY <= (endButtonY + 50)) {
// Zeichne den initialen Button
drawInitialButton();
// Setze initialScreen auf true
initialScreen = true;
}
}
// Warte, bis der Touchscreen losgelassen wird
while (ts.touched()) {
delay(10);
}
}
}
void setup() {
Serial.begin(9600);
// Initialisiere das erste Display
tft1.begin();
tft1.setRotation(1);
tft1.fillScreen(ST7796S_BLACK);
// Initialisiere den ersten Touchscreen
if (!ts1.begin()) {
while (1);
}
ts1.setRotation(1);
// Initialisiere das zweite Display
tft2.begin();
tft2.setRotation(1);
tft2.fillScreen(ST7796S_BLACK);
// Initialisiere den zweiten Touchscreen
if (!ts2.begin()) {
while (1);
}
ts2.setRotation(1);
// Position des Buttons initialisieren
rectX = (tft1.width() - rectWidth) / 2;
rectY = (tft1.height() - rectHeight) / 2;
// Zeichne den initialen Button auf beiden Displays
drawInitialButton();
}
void loop() {
handleTouch(ts1, tft1, "Display 1");
handleTouch(ts2, tft2, "Display 2");
if (gameScreen) {
// Überprüfen, ob die Spielzeit abgelaufen ist
int timeLeft = gameTime - (millis() - gameStartTime) / 1000;
static int lastTimeLeft = -1;
if (timeLeft <= 0) {
// Zeichne den initialen Button auf beiden Displays
drawInitialButton();
// Setze initialScreen auf true
initialScreen = true;
gameScreen = false;
} else if (timeLeft != lastTimeLeft) {
// Aktualisiere das Spielinterface nur, wenn sich der Timer ändert
drawGameScreen(timeLeft, hits);
lastTimeLeft = timeLeft;
}
}
}