ESP32 mit 2,8 Zoll TFT Bei­spie­le Biblio­thek ILI9341

Benö­tig­te Bibliotheken

Gra­fik
Touch­screen
DHT-Sen­sor
BMP280-Sen­sor
Foto­schau
Schrif­ten

Touch­screen abfragen

#include "Adafruit_ILI9341.h"
#include "XPT2046_Touchscreen_TT.h"

// Adafruit Schrift
#include "Fonts/FreeSans9pt7b.h"

#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

// TFT-Pins (Software-SPI)
#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// Touchscreen SPI-Pins
#define TOUCH_MOSI 32  
#define TOUCH_MISO 39  
#define TOUCH_CLK 25   
#define TOUCH_CS 33

// IRQ-Pin
#define TOUCH_IRQ 36

// SPI-Pins als Hardware-SPI
SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(TOUCH_CS, TOUCH_IRQ);

bool FarbwechselLinkerButton = false;
bool FarbwechselRechterButton = false;

// Touchscreen Koordinaten (z = Druck)
int x, y, z;

void setup() 
{
  Serial.begin(9600);

  // SPI-Bus für den Touchscreen starten
  touchscreenSPI.begin(TOUCH_CLK, TOUCH_MISO, TOUCH_MOSI, TOUCH_CS);
  touchscreen.begin(touchscreenSPI);

  /*
    wenn die Bildschirm-Koordinaten und die Touchscreen-Kordinaten
    nicht übereinstimmen (Touchscreen ist "falsch" herum)
    Rotation des Touchscreen setzen:
    touchscreen.setRotation(3);
  */

  // TFT starten
  tft.begin();

  // Hintergrundbeleuchtung einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
  
  // Bildschirm drehen
  tft.setRotation(1);

  /*
    wenn die Bildschirm-Koordinaten und die Touchscreen-Kordinaten
    nicht übereinstimmen (Touchscreen ist "falsch" herum)
    Rotation des Touchscreen setzen:
    touchscreen.setRotation(3);
  */

  tft.fillScreen(SCHWARZ);

  // linker Button  
  tft.fillRect(50, 100, 100, 50, ROT);
  tft.drawRoundRect(50, 100, 100, 50, 5, WEISS);
  
  // rechter Button
  tft.fillRect(180, 100, 100, 50, GELB);
  tft.drawRoundRect(180, 100, 100, 50, 5, WEISS);
  tft.setTextSize(2);
}

void loop() 
{
  // wenn der Touchscreen berührt wurde
  if (touchscreen.tirqTouched() && touchscreen.touched()) 
  {
    // Punkte x, y und Druck (z) ermitteln
    TS_Point Punkt = touchscreen.getPoint();

    /*
      die "Rohwerte" der Punkte x und y bewegen sich zwischen 1 und 3800 bzw. 3900
      daher müssen sie mit map auf die korrekten Bildschirmmaße
      korrigiert werden
    */
    x = map(Punkt.x, 240, 3800, 1, tft.width());
    y = map(Punkt.y, 320, 3900, 1, tft.height());
    
    z = Punkt.z;

    // linker Button Koordinaten abfragen
    if (x >= 50 && x <= 150 && y >= 100 && y <= 150) 
    {
      if (FarbwechselLinkerButton) 
      {
        tft.fillRect(50, 100, 100, 50, SCHWARZ);
        tft.fillRect(50, 100, 100, 50, ROT);
        tft.drawRoundRect(50, 100, 100, 50, 5, WEISS);
      }
      
      else 
      {
        tft.fillRect(50, 100, 100, 50, SCHWARZ);
        tft.fillRect(50, 100, 100, 50, BLAU);
        tft.drawRoundRect(50, 100, 100, 50, 5, WEISS);
      }
      FarbwechselLinkerButton = !FarbwechselLinkerButton;
    }

    // rechter Button Koordinaten abfragen
    if (x >= 180 && x <= 280 && y >= 100 && y <= 150) 
    {
      if (FarbwechselRechterButton) 
      {
        tft.fillRect(180, 100, 100, 50, SCHWARZ);
        tft.fillRect(180, 100, 100, 50, MAGENTA);
        tft.drawRoundRect(180, 100, 100, 50, 5, WEISS);
      }

      else 
      {
        tft.fillRect(180, 100, 100, 50, SCHWARZ);
        tft.fillRect(180, 100, 100, 50, GELB);
        tft.drawRoundRect(180, 100, 100, 50, 5, WEISS);
      }
      FarbwechselRechterButton = !FarbwechselRechterButton;
    }
    KoordinatenAnzeigen(x, y, z);

    delay(100);
  }
}

void KoordinatenAnzeigen(int x, int y, int z) 
{
  Serial.print("x-Koordinate = ");
  Serial.print(x);
  Serial.print(" | y-Koordinate = ");
  Serial.print(y);
  Serial.print(" | Druck = ");
  Serial.print(z);
  Serial.println();

  tft.fillRect(1, 1, tft.width(), 90, SCHWARZ);
  tft.setCursor(10, 30);
  tft.setFont(&FreeSans9pt7b);
  tft.println("x-Koordinate: " + String(x));
  tft.println(" y-Koordinate: " + String(y));
}

Tem­pe­ra­tur mit DHT

#include "Adafruit_ILI9341.h"
#include "U8g2_for_Adafruit_GFX.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

#include "DHT.h"

int SENSOR_DHT = 22;

#define SensorTyp DHT22

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp); 

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define PINK        0xFE19
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

// Farben Messwerte
#define FarbeLuftfeuchtigkeit GRUEN
#define FarbeTemperatur BLAU

void setup() 
{
  // Sensor starten
  dht.begin();

  // Backlight einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(SCHWARZ);

  // Schriften von u8g2 tft zuordnen
  u8g2Schriften.begin(tft); 
}

void loop()
{
  TemperaturAnzeigen();
  delay(10000);
}

void TemperaturAnzeigen()
{
  // Temperatur lesen 
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen 
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // Bereich für die Messwerte löschen
  tft.fillRect(20, 40, 270, 150, SCHWARZ);

  u8g2Schriften.setCursor(20, 100);
  u8g2Schriften.setForegroundColor(FarbeLuftfeuchtigkeit);   
  u8g2Schriften.setFont(u8g2_font_logisoso58_tf);   
  u8g2Schriften.print(Luftfeuchtigkeit + "%");

  u8g2Schriften.setCursor(20, 180);
  u8g2Schriften.setForegroundColor(FarbeTemperatur);
  u8g2Schriften.print(Temperatur + "°C");
}

Tem­pe­ra­tur DHT mit Touchscreen

#include "Adafruit_ILI9341.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "XPT2046_Touchscreen_TT.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

#include "DHT.h"

int SENSOR_DHT = 22;

#define SensorTyp DHT22

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp); 

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// Touchscreen SPI-Pins
#define TOUCH_IRQ 36
#define TOUCH_MOSI 32  
#define TOUCH_MISO 39  
#define TOUCH_CLK 25   
#define TOUCH_CS 33

// Touchscreen Koordinaten (z = Druck)
int x, y, z;

// SPI-Pins als Hardware-SPI
SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(TOUCH_CS, TOUCH_IRQ);

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define PINK        0xFE19
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

// Farben Messwerte/Piktogramm
#define FarbeLuftfeuchtigkeit BLAU
#define FarbeTemperatur ROT

// Arrays Piktogramme
const unsigned char Thermometer [] PROGMEM = {
	// 'Thermometer, 34x70px
	0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 
	0x7c, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x07, 0x80, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0x00, 0x00, 0xe0, 
	0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 
	0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 
	0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 
	0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 
	0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 
	0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 
	0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc3, 0xe1, 0xc0, 
	0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x0f, 0xc3, 0xf1, 0xc0, 0x00, 
	0x0f, 0xc3, 0xf1, 0xc0, 0x00, 0x0f, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 
	0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 
	0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x03, 0xc3, 0xf1, 0xf0, 0x00, 0x07, 0xc3, 0xf0, 
	0xf8, 0x00, 0x0f, 0x03, 0xf0, 0x7c, 0x00, 0x0e, 0x03, 0xe0, 0x3c, 0x00, 0x1c, 0x07, 0xf0, 0x1e, 
	0x00, 0x3c, 0x1f, 0xfc, 0x0f, 0x00, 0x38, 0x3f, 0xfe, 0x0f, 0x00, 0x78, 0x7f, 0xff, 0x07, 0x80, 
	0x70, 0x7f, 0xff, 0x87, 0x80, 0x70, 0x7f, 0xff, 0x83, 0x80, 0xf0, 0xff, 0xff, 0x83, 0xc0, 0xf0, 
	0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 
	0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0x83, 0xc0, 0x70, 0x7f, 0xff, 0x83, 0x80, 0x70, 0x7f, 0xff, 
	0x87, 0x80, 0x78, 0x3f, 0xff, 0x07, 0x80, 0x38, 0x3f, 0xfe, 0x0f, 0x00, 0x3c, 0x0f, 0xfc, 0x0f, 
	0x00, 0x1e, 0x03, 0xe0, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x3e, 0x00, 0x0f, 0x00, 0x00, 0x7c, 0x00, 
	0x07, 0xe0, 0x01, 0xf8, 0x00, 0x03, 0xf8, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 
	0x7f, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00
};

const unsigned char Regen [] PROGMEM = {
	// 'Regen, 60x49px
	0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x02, 0x08, 0x21, 0x04, 0x10, 0x00, 0x00, 0x00, 0x06, 0x18, 0x63, 0x0c, 0x30, 0x80, 0x00, 
	0x00, 0x06, 0x10, 0x63, 0x0c, 0x31, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x20, 0x84, 0x10, 0x41, 0x08, 0x20, 0x00, 0x00, 0x61, 0x8c, 0x30, 0xc3, 0x18, 0x60, 0x00, 
	0x08, 0xc1, 0x8c, 0x30, 0xc3, 0x18, 0x61, 0x00, 0x00, 0x41, 0x04, 0x20, 0x82, 0x08, 0x40, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 0x86, 0x18, 0x43, 0x04, 0x30, 0x80, 
	0x18, 0x71, 0x86, 0x18, 0xc3, 0x0c, 0x31, 0x80, 0x18, 0x21, 0x84, 0x10, 0xc3, 0x0c, 0x21, 0x80, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x18, 0x21, 0x04, 0x10, 0x42, 0x18, 0x40, 
	0x86, 0x18, 0x63, 0x0c, 0x30, 0xc6, 0x18, 0xc0, 0x86, 0x10, 0x63, 0x0c, 0x30, 0xc6, 0x18, 0xc0, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x18, 0x21, 0x04, 0x10, 0xc2, 0x0c, 0x21, 0x00, 0x30, 0x63, 0x0c, 0x31, 0xc6, 0x0c, 0x63, 0x00, 
	0x30, 0x63, 0x0c, 0x31, 0x86, 0x18, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x06, 0x10, 0x43, 0x08, 0x20, 0x86, 0x10, 0x00, 0x06, 0x30, 0xc3, 0x18, 0x61, 0x86, 0x30, 0x00, 
	0x04, 0x30, 0xc2, 0x18, 0x61, 0x8c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x0c, 0x30, 0xc6, 0x18, 0x61, 0x00, 0x00, 
	0x00, 0x00, 0x61, 0xc6, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x86, 0x10, 0x60, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void setup() 
{
  Serial.begin(9600);

  // Sensor starten
  dht.begin();

  // SPI-Bus für den Touchscreen starten
  touchscreenSPI.begin(TOUCH_CLK, TOUCH_MISO, TOUCH_MOSI, TOUCH_CS);
  touchscreen.begin(touchscreenSPI);

  // Backlight einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(SCHWARZ);

  // Schriften von u8g2 tft zuordnen
  u8g2Schriften.begin(tft); 
  
  // Button
  tft.fillRect(20, 180, 200, 50, ROT);
  tft.drawRoundRect(20, 180, 200, 50, 5, WEISS);
  tft.drawRoundRect(19, 179, 199, 49, 5, WEISS);
  u8g2Schriften.setCursor(30, 210);
  u8g2Schriften.setForegroundColor(WEISS);
  u8g2Schriften.setBackgroundColor(ROT);
  u8g2Schriften.setFont(u8g2_font_inb16_mf);
  u8g2Schriften.print("Aktualisieren");

  /*
    Piktogramme anzeigen
    Parameter: 
    Position x-/y-Koordinate
    Name des Arrays
    Bildgröße in Pixel x/y
    Farbe
  */
  tft.drawBitmap(1, 30, Regen, 60, 49, FarbeLuftfeuchtigkeit);
  tft.drawBitmap(10, 100, Thermometer, 34, 70, FarbeTemperatur);

  TemperaturAnzeigen();
}

void loop()
{
  // wenn der Touchscreen berührt wurde
  if (touchscreen.tirqTouched() && touchscreen.touched()) 
  {
    // Punkte x, y und Druck (z) ermitteln
    TS_Point Punkt = touchscreen.getPoint();

    /*
      die "Rohwerte" der Punkte x und y bewegen sich zwischen 1 und 3800 bzw. 3900
      daher müssen sie mit map auf die korrekten Bildschirmmaße
      korrigiert werden
    */
    x = map(Punkt.x, 240, 3800, 1, tft.width());
    y = map(Punkt.y, 320, 3900, 1, tft.height());
    
    z = Punkt.z;
    
    // Kordinaten im Seriellen Monitor anzeigen
    KoordinatenAnzeigen(x, y, z);
    
    // die Koordinaten werden durch die Punkte  des Buttons festgelegt
    if (x >= 20 && x <= 220 && y >= 180 && y <= 250) 
    {
      TemperaturAnzeigen();
    }
  }
  delay(100);
}

void TemperaturAnzeigen()
{
  // Temperatur lesen 
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen 
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // Bereich für die Messwerte löschen
  tft.fillRect(65, 10, 270, 150, SCHWARZ);

  u8g2Schriften.setBackgroundColor(SCHWARZ);
  u8g2Schriften.setCursor(70, 80);
  u8g2Schriften.setForegroundColor(FarbeLuftfeuchtigkeit);   
  u8g2Schriften.setFont(u8g2_font_logisoso58_tf);   
  u8g2Schriften.print(Luftfeuchtigkeit + "%");

  u8g2Schriften.setCursor(70, 160);
  u8g2Schriften.setForegroundColor(FarbeTemperatur);   
  u8g2Schriften.setForegroundColor(FarbeTemperatur);
  u8g2Schriften.print(Temperatur + "°C");
}

void KoordinatenAnzeigen(int x, int y, int z) 
{
  Serial.print("x-Koordinate = ");
  Serial.print(x);
  Serial.print(" | y-Koordinate = ");
  Serial.print(y);
  Serial.print(" | Druck = ");
  Serial.print(z);
  Serial.println();
}

Tem­pe­ra­tur mit BMP280

#include "Adafruit_ILI9341.h"
#include "U8g2_for_Adafruit_GFX.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

#include "Adafruit_BMP280.h"

Adafruit_BMP280 bmp;

#define SDA_PIN 22
#define SCL_PIN 27

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define PINK        0xFE19
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

void setup() 
{
  // Sensor starten
  Wire.begin(SDA_PIN, SCL_PIN);
  bmp.begin();

  // Backlight einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(SCHWARZ);

  // Schriften von u8g2 tft zuordnen
  u8g2Schriften.begin(tft); 
}

void loop()
{
  DatenAnzeigen();
  delay(10000);
}

void DatenAnzeigen()
{
  // Temperatur lesen 
  String Temperatur = String(bmp.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  String Luftdruck = String(bmp.readPressure() / 100);
  Luftdruck.replace(".", ",");

  // Bereich für die Messwerte löschen
  tft.fillRect(1, 40, 300, 150, SCHWARZ);

  u8g2Schriften.setCursor(10, 100);
  u8g2Schriften.setForegroundColor(BLAU);   
  u8g2Schriften.setFont(u8g2_font_logisoso42_tf);   
  u8g2Schriften.print(Luftdruck + " hPa");

  u8g2Schriften.setCursor(10, 180);
  u8g2Schriften.setForegroundColor(ROT);
  u8g2Schriften.print(Temperatur + "°C");
}

Ana­lo­ge Uhr

#include "WiFi.h"
#include "time.h"
#include "Adafruit_ILI9341.h"
#include "Fonts/FreeSans9pt7b.h"
#include "Fonts/FreeSans12pt7b.h"

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// WiFi-Daten
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

// Variablen des TFTs (Höhe, Breite, Radius)
const int MitteHoehe = 120;
const int MitteBreite = 120;
const int Radius = 120;

// Multiplikatoren für x- y-Positionen der Stunden, Minuten und Sekunden
float SekundePosX = 0, SekundePosY = 0, MinutePosX = 0, MinutePosY = 0, StundePosX = 0, StundePosY = 0;
float GradSekunden = 0, GradMinuten = 0, GradStunden = 0;

// x- y-Koordinaten für die Anzeige Stunden, Minuten und Sekunden
int SekundenZeigerX = MitteHoehe, SekundenZeigerY = MitteHoehe;
int MinutenZeigerX = MitteHoehe, MinutenZeigerY = MitteHoehe;
int StundenZeigerX = MitteHoehe, StundenZeigerY = MitteHoehe; 

// Start wird nur beim ersten Start für den Aufbau des TFTs benötigt
bool Start = 1;

// Variablen für die Markierungen und Punkte und Striche des Ziffernblatts
float PosX, PosY;
int PunktX, PunktY, PunktX1, PunktX2, PunktY1, PunktY2;

// Variablen für die Zeit
int Stunden, Minuten, Sekunden;

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define PINK        0xFE19
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

// Farben innerer Kreis, Randfarbe und Zeigerfarbe
// die Farben der Zeiger können aber auch individuell gesetzt werden
const int Kreisfarbe = SCHWARZ;
const int Zeigerfarbe = WEISS;
const int Randfarbe = BORDEAUX;

// true -> Datum anzeigen
// false -> Datum nicht anzeigen
bool DatumAnzeigen = true;

// true -> Sekundenzeiger nur als Kreis
bool SekundenzeigerKreis = false;

// Ziffern 12 3 6 9 anzeigen/nicht anzeigen
bool Ziffernanzeigen = true;

// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"

/*
  Liste der Zeitzonen
  https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
  CEST = Central European SuMinutener Time von
  M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
  bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"

// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;

/* 
  Struktur tm
  tm_hour -> Stunde: 0 bis 23
  tm_min -> Minuten: 0 bis 59
  tm_sec -> Sekunden 0 bis 59
  tm_mday -> Tag 1 bis 31
  tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
  tm_year -> Jahre seit 1900
  tm_yday -> vergangene Tage seit 1. Januar des Jahres
  tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;

// 1-Bit Canvas definieren, Breite 240, Höhe 80 Pixel
GFXcanvas1 Bereich(240, 80);

unsigned long Zeitmessung = 0;  

void setup() 
{
  Serial.begin(9600);

  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);

  Serial.println("------------------------");

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(Router);
  Serial.print("IP über DHCP: ");
  Serial.println(WiFi.localIP());

  // Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Zeit in Stunden, Minuten und Sekunden
  Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
  
  // Hintergrundbeleuchtung einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(Kreisfarbe);

  // 4 Pixel breiter äußerer Rand, Farbe au der Farbpalette wählen
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 1, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 2, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 3, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 4, Randfarbe);

  // innere Fläche bis auf den Rand von 4 Pixeln vollständig löschen
  // wenn andere Farbe als äußerer Rand gewählt wird ergibt sich ein schmaler Rand
  tft.fillCircle(MitteHoehe, MitteBreite, Radius - 4, Kreisfarbe);

  /*
    alle 30° Linie am Rand als Stundenmarkierung zeichnen
    DEG_TO_RAD (= PI/180 = 0.0174532925) -> Winkel in Bogenmaß umrechnen
    sin/cos berechnen die x-/y-Kordinaten des Punktes auf der Kreislinie
  */
  for (int i = 0; i < 360; i += 30) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // kurze Linien zeichnen, von 114 bis 100 vom äußeren Rand aus
    // Farbe individuell wählbar
    int PunktX1 = PosX * 110 + Radius;
    int PunktY1 = PosY * 110 + Radius;
    int PunktX2 = PosX * 100 + Radius;
    int PunktY2 = PosY * 100 + Radius;

    // keine Striche an der Position der Zahlen
    if (PunktX1 == 10 || PunktX1 == 120 || PunktX1 == 230)
    {
      tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Kreisfarbe);
    }
    else tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Zeigerfarbe);
  }

  // alle 6 Grad Punkte als Sekundenmarkierung zeichnen
  for (int i = 0; i < 360; i += 6) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // Positionen der Punkte
    // 108 -> Abstand vom Mittelpunkt
    PunktX = PosX * 108 + Radius;
    PunktY = PosY * 108 + Radius;
    tft.drawPixel(PunktX, PunktY, Zeigerfarbe);  
  }

   // Markierung 12 3 6 9
  if (Ziffernanzeigen)
  {
    tft.setFont(&FreeSans9pt7b);
    tft.setTextColor(Zeigerfarbe);
    tft.setCursor(110, 25);
    tft.print("12");

    tft.setCursor(10, 125);
    tft.print("9");

    tft.setCursor(220, 125);
    tft.print("3");
  
    tft.setCursor(113, 230);
    tft.print("6");
  }
  if (DatumAnzeigen) ZeigeDatum();
  
  Zeitmessung = millis() + 1000; 
}

void loop() 
{
  // Sekunden weiter zählen
  if (Zeitmessung < millis()) 
  {
    Zeitmessung += 1000;
    Sekunden++;  

    if (Sekunden == 60) 
    { 
      Sekunden = 0; 
      Minuten++; 

      // Zeit jede Minute mit Zeitserver synchronisieren
      // aktuelle Zeit holen
      time(&aktuelleZeit);

      // localtime_r -> Zeit in die lokale Zeitzone setzen
      localtime_r(&aktuelleZeit, &Zeit);

      // Zeit in Stunden, Minuten und Sekunden
      Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
      
      // Datum anzeigen/nicht anzeigen
      if (DatumAnzeigen) ZeigeDatum();

      if (Minuten > 59) 
      {
        Minuten = 0;
        Stunden++;  
        if (Stunden > 23) 
        {
          Stunden = 0;
        }
      }
    }

    // Vorausberechnung der x- und y-Koordinaten
    // 0-59 -> 0-354 = Faktor 6
    GradSekunden = Sekunden * 6;    

    // Minuten+Sekunden in Relation zu 3600 setzen
    // 60 / 3600 = 0.01666667         
    GradMinuten = Minuten * 6 + GradSekunden * 0.01666667; 

    // 30 / 3600 = 0.0833333
    // Stunden+Minuten in Relation zu 360 setzen
    // 0-11 -> 0-360 
    GradStunden = Stunden * 30 + GradMinuten * 0.0833333;  // 0-11 -> 0-360 
    StundePosX = cos((GradStunden - 90) * DEG_TO_RAD);
    StundePosY = sin((GradStunden - 90) * DEG_TO_RAD);

    MinutePosX = cos((GradMinuten - 90) * DEG_TO_RAD) ;
    MinutePosY = sin((GradMinuten - 90) * DEG_TO_RAD);

    SekundePosX = cos((GradSekunden - 90) * DEG_TO_RAD);
    SekundePosY = sin((GradSekunden - 90) * DEG_TO_RAD);

    // nach jeder Minute Minuten-/Stundenzeiger löschen
    // oder einmalig beim Start der Anzeige
    if (Sekunden == 0 || Start) 
    {
      Start = false;
      tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);  

      // 62 Pixel -> Länge des Stundenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      StundenZeigerX = StundePosX * 62 + MitteHoehe + 1;
      StundenZeigerY = StundePosY * 62 + MitteHoehe + 1;
      tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

      // 84 Pixel -> Länge des Minutenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      MinutenZeigerX = MinutePosX * 84 + MitteHoehe;
      MinutenZeigerY = MinutePosY * 84 + MitteHoehe + 1;
    }

    // Sekundenzeiger löschen
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

    // Kreis am Sekundenzeiger löschen, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, Kreisfarbe);

    // 85 Pixel -> Länge des Sekundenzeigers
    SekundenZeigerX = SekundePosX * 85 + MitteHoehe + 1;
    SekundenZeigerY = SekundePosY * 85 + MitteHoehe + 1;

    // Zeiger neu zeichnen
    // Sekunden Linie nur anzeigen wenn SekundenzeigerKreis false
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, ROT);
    
    // Minuten
    tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Stunden
    tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Kreis an der Spitze des Sekundenzeigers, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, ROT);

    // Mittelpunkt zeichnen
    tft.fillCircle(MitteHoehe, MitteHoehe + 1, 3, Zeigerfarbe); 
  }
}

void ZeigeDatum()
{
  Bereich.fillScreen(SCHWARZ);
  Bereich.setFont(&FreeSans12pt7b);
  Bereich.setCursor(30, 30);

  // Wochentag anzeigen
  switch (Zeit.tm_wday) 
  {
    case 0:
      Bereich.print("Sonntag");
      break;
    case 1:
      Bereich.print("Montag");
      break;
    case 2:
      Bereich.print("Dienstag");
      break;
    case 3:
      Bereich.print("Mittwoch");
      break;
    case 4:
      Bereich.print("Donnerstag");
      break;
    case 5:
      Bereich.print("Freitag");
      break;
    case 6:
      Bereich.print("Samstag");
      break;
  }
      
  Bereich.setCursor(30, 60);
  if (Zeit.tm_mday < 10) Bereich.print("0");
  Bereich.print(Zeit.tm_mday);
  Bereich.print(".");

  // Monat: führende 0 ergänzen
  if (Zeit.tm_mon < 9) Bereich.print("0");
    
  // Zählung beginnt mit 0 -> +1
  Bereich.print(Zeit.tm_mon + 1);
  Bereich.print(".");

  // Anzahl Jahre seit 1900
  Bereich.print(Zeit.tm_year + 1900);
  tft.drawBitmap(0, 245, Bereich.getBuffer(), Bereich.width(), Bereich.height(), GRUEN, SCHWARZ);
}

Ana­lo­ge Uhr mit Temperaturanzeige

#include "WiFi.h"
#include "time.h"
#include "Adafruit_ILI9341.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "DHT.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

int SENSOR_DHT = 22;

#define SensorTyp DHT22

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp); 

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// WiFi-Daten
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

// Variablen des TFTs (Höhe, Breite, Radius)
const int MitteHoehe = 120;
const int MitteBreite = 120;
const int Radius = 120;

// Multiplikatoren für x- y-Positionen der Stunden, Minuten und Sekunden
float SekundePosX = 0, SekundePosY = 0, MinutePosX = 0, MinutePosY = 0, StundePosX = 0, StundePosY = 0;
float GradSekunden = 0, GradMinuten = 0, GradStunden = 0;

// x- y-Koordinaten für die Anzeige Stunden, Minuten und Sekunden
int SekundenZeigerX = MitteHoehe, SekundenZeigerY = MitteHoehe;
int MinutenZeigerX = MitteHoehe, MinutenZeigerY = MitteHoehe;
int StundenZeigerX = MitteHoehe, StundenZeigerY = MitteHoehe; 

// Start wird nur beim ersten Start für den Aufbau des TFTs benötigt
bool Start = 1;

// Variablen für die Markierungen und Punkte und Striche des Ziffernblatts
float PosX, PosY;
int PunktX, PunktY, PunktX1, PunktX2, PunktY1, PunktY2;

// Variablen für die Zeit
int Stunden, Minuten, Sekunden;

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define PINK        0xFE19
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

// Farben innerer Kreis, Randfarbe und Zeigerfarbe
// die Farben der Zeiger können aber auch individuell gesetzt werden
const int Kreisfarbe = SCHWARZ;
const int Zeigerfarbe = WEISS;
const int Randfarbe = BORDEAUX;

// true -> Datum anzeigen
// false -> Datum nicht anzeigen
bool DatumAnzeigen = true;

// true -> Sekundenzeiger nur als Kreis
bool SekundenzeigerKreis = false;

// Ziffern 12 3 6 9 anzeigen/nicht anzeigen
bool Ziffernanzeigen = true;

// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"

/*
  Liste der Zeitzonen
  https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
  CEST = Central European SuMinutener Time von
  M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
  bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"

// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;

/* 
  Struktur tm
  tm_hour -> Stunde: 0 bis 23
  tm_min -> Minuten: 0 bis 59
  tm_sec -> Sekunden 0 bis 59
  tm_mday -> Tag 1 bis 31
  tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
  tm_year -> Jahre seit 1900
  tm_yday -> vergangene Tage seit 1. Januar des Jahres
  tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;

unsigned long Zeitmessung = 0;  

void setup() 
{
  // Sensor starten
  dht.begin();

    // Schriften von u8g2 tft zuordnen
  u8g2Schriften.begin(tft); 

  Serial.begin(9600);

  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);

  Serial.println("------------------------");

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(Router);
  Serial.print("IP über DHCP: ");
  Serial.println(WiFi.localIP());

  // Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Zeit in Stunden, Minuten und Sekunden
  Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
  
  // Hintergrundbeleuchtung einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(Kreisfarbe);

  // 4 Pixel breiter äußerer Rand, Farbe au der Farbpalette wählen
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 1, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 2, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 3, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 4, Randfarbe);

  // innere Fläche bis auf den Rand von 4 Pixeln vollständig löschen
  // wenn andere Farbe als äußerer Rand gewählt wird ergibt sich ein schmaler Rand
  tft.fillCircle(MitteHoehe, MitteBreite, Radius - 4, Kreisfarbe);

  /*
    alle 30° Linie am Rand als Stundenmarkierung zeichnen
    DEG_TO_RAD (= PI/180 = 0.0174532925) -> Winkel in Bogenmaß umrechnen
    sin/cos berechnen die x-/y-Kordinaten des Punktes auf der Kreislinie
  */
  for (int i = 0; i < 360; i += 30) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // kurze Linien zeichnen, von 114 bis 100 vom äußeren Rand aus
    // Farbe individuell wählbar
    int PunktX1 = PosX * 110 + Radius;
    int PunktY1 = PosY * 110 + Radius;
    int PunktX2 = PosX * 100 + Radius;
    int PunktY2 = PosY * 100 + Radius;

    // keine Striche an der Position der Zahlen
    if (PunktX1 == 10 || PunktX1 == 120 || PunktX1 == 230)
    {
      tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Kreisfarbe);
    }
    else tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Zeigerfarbe);
  }

  // alle 6 Grad Punkte als Sekundenmarkierung zeichnen
  for (int i = 0; i < 360; i += 6) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // Positionen der Punkte
    // 108 -> Abstand vom Mittelpunkt
    PunktX = PosX * 108 + Radius;
    PunktY = PosY * 108 + Radius;
    tft.drawPixel(PunktX, PunktY, Zeigerfarbe);  
  }

  // Markierung 12 3 6 9
  if (Ziffernanzeigen)
  {
    u8g2Schriften.setFont(u8g2_font_helvB14_tf);  
    u8g2Schriften.setForegroundColor(Zeigerfarbe);
    u8g2Schriften.setCursor(110, 25);
    u8g2Schriften.print("12");

    u8g2Schriften.setCursor(10, 125);
    u8g2Schriften.print("9");

    u8g2Schriften.setCursor(220, 125);
    u8g2Schriften.print("3");
  
    u8g2Schriften.setCursor(113, 230);
    u8g2Schriften.print("6");
  }

  if (DatumAnzeigen)
  {
    ZeigeDatum();
  }

  TemperaturAnzeigen();
}

void loop() 
{
  // Sekunden weiter zählen
  if (Zeitmessung < millis()) 
  {
    Zeitmessung += 1000;
    Sekunden++;  

    if (Sekunden == 60) 
    { 
      Sekunden = 0; 
      Minuten++; 

      TemperaturAnzeigen();
      
      // Datum anzeigen/nicht anzeigen
      if (DatumAnzeigen) ZeigeDatum();
      
      // Zeit jede Minute mit Zeitserver synchronisieren
      // aktuelle Zeit holen
      time(&aktuelleZeit);

      // localtime_r -> Zeit in die lokale Zeitzone setzen
      localtime_r(&aktuelleZeit, &Zeit);

      // Zeit in Stunden, Minuten und Sekunden
      Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);

      if (Minuten > 59) 
      {
        Minuten = 0;
        Stunden++;  
        if (Stunden > 23) 
        {
          Stunden = 0;
        }
      }
    }

    // Vorausberechnung der x- und y-Koordinaten
    // 0-59 -> 0-354 = Faktor 6
    GradSekunden = Sekunden * 6;    

    // Minuten+Sekunden in Relation zu 3600 setzen
    // 60 / 3600 = 0.01666667         
    GradMinuten = Minuten * 6 + GradSekunden * 0.01666667; 

    // 30 / 3600 = 0.0833333
    // Stunden+Minuten in Relation zu 360 setzen
    // 0-11 -> 0-360 
    GradStunden = Stunden * 30 + GradMinuten * 0.0833333;  // 0-11 -> 0-360 
    StundePosX = cos((GradStunden - 90) * DEG_TO_RAD);
    StundePosY = sin((GradStunden - 90) * DEG_TO_RAD);

    MinutePosX = cos((GradMinuten - 90) * DEG_TO_RAD) ;
    MinutePosY = sin((GradMinuten - 90) * DEG_TO_RAD);

    SekundePosX = cos((GradSekunden - 90) * DEG_TO_RAD);
    SekundePosY = sin((GradSekunden - 90) * DEG_TO_RAD);

    // nach jeder Minute Minuten-/Stundenzeiger löschen
    // oder einmalig beim Start der Anzeige
    if (Sekunden == 0 || Start) 
    {
      Start = false;
      tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);  

      // 62 Pixel -> Länge des Stundenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      StundenZeigerX = StundePosX * 62 + MitteHoehe + 1;
      StundenZeigerY = StundePosY * 62 + MitteHoehe + 1;
      tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

      // 84 Pixel -> Länge des Minutenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      MinutenZeigerX = MinutePosX * 84 + MitteHoehe;
      MinutenZeigerY = MinutePosY * 84 + MitteHoehe + 1;
    }

    // Sekundenzeiger löschen
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

    // Kreis am Sekundenzeiger löschen, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, Kreisfarbe);

    // 85 Pixel -> Länge des Sekundenzeigers
    SekundenZeigerX = SekundePosX * 85 + MitteHoehe + 1;
    SekundenZeigerY = SekundePosY * 85 + MitteHoehe + 1;

    // Zeiger neu zeichnen
    // Sekunden Linie nur anzeigen wenn SekundenzeigerKreis false
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, ROT);
    
    // Minuten
    tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Stunden
    tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Kreis an der Spitze des Sekundenzeigers, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, ROT);

    // Mittelpunkt zeichnen
    tft.fillCircle(MitteHoehe, MitteHoehe + 1, 3, Zeigerfarbe); 
  }
}

void ZeigeDatum()
{
  tft.fillRect(10, 250, 240, 30, SCHWARZ);

  u8g2Schriften.setForegroundColor(GRUEN);   
  u8g2Schriften.setBackgroundColor(SCHWARZ);
  u8g2Schriften.setFont(u8g2_font_helvB14_tf);   
  u8g2Schriften.setCursor(10, 270);

  // Wochentag anzeigen
  switch (Zeit.tm_wday) 
  {
    case 0:
      u8g2Schriften.print("Sonntag");
      break;
    case 1:
      u8g2Schriften.print("Montag");
      break;
    case 2:
      u8g2Schriften.print("Dienstag");
      break;
    case 3:
      u8g2Schriften.print("Mittwoch");
      break;
    case 4:
      u8g2Schriften.print("Donnerstag");
      break;
    case 5:
      u8g2Schriften.print("Freitag");
      break;
    case 6:
      u8g2Schriften.print("Samstag");
      break;
  }

  u8g2Schriften.print(", ");
      
  if (Zeit.tm_mday < 10) u8g2Schriften.print("0");
  u8g2Schriften.print(Zeit.tm_mday);
  u8g2Schriften.print(".");

  // Monat: führende 0 ergänzen
  if (Zeit.tm_mon < 9) u8g2Schriften.print("0");
    
  // Zählung beginnt mit 0 -> +1
  u8g2Schriften.print(Zeit.tm_mon + 1);
  u8g2Schriften.print(".");

  // Anzahl Jahre seit 1900
  u8g2Schriften.print(Zeit.tm_year + 1900);
}

void TemperaturAnzeigen()
{
  // Temperatur lesen 
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen 
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // Anzeigebereich löschen
  tft.fillRect(10, 275, 240, 45, SCHWARZ);
  u8g2Schriften.setForegroundColor(BLAU);   
  u8g2Schriften.setBackgroundColor(SCHWARZ);
  u8g2Schriften.setCursor(10, 310);
  u8g2Schriften.setFont(u8g2_font_logisoso22_tf);   
  u8g2Schriften.print(Luftfeuchtigkeit + "%");

  u8g2Schriften.setCursor(120, 310);
  u8g2Schriften.setForegroundColor(ROT);
  u8g2Schriften.print(Temperatur + "°C");
}

Foto­schau

#include "SdFat.h"
#include "Adafruit_ILI9341.h"
#include "Adafruit_ImageReader.h"

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

/* 
  SD VSPI Standard-Pins
  CLK    18
  MOSI   23
  MISO   19
  CS      5
*/

// Objekt tft der Bibliothek Adafruit_ILI9341 erstellen
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// Objekt SD der Bibliothek SdFat erstellen
SdFat SD;              

// Objekt des Kartenlesers wird an das Dateisystem der SD-Karte übertragen
Adafruit_ImageReader reader(SD);

Adafruit_Image Bild;  

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F

// 3 = FAT32
#define SD_FAT_TYPE 3

// SPI-Geschwindigkeit
#define SPI_SPEED SD_SCK_MHZ(4)

// CSPin der SD-Karte
int CSPin = 5;

// Anzeigedauer
int Intervall = 6000;

bool Beschreibung = true;

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);
 
  // TFT starten
  tft.begin();
  
  // Hintergrundbeleuchtung einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
  
  // Rotation anpassen
  tft.setRotation(3);

  // schwarzer Hintergrund
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(2);
  tft.setTextColor(WEISS);
  tft.setCursor(1, 20);

  /*
     SD-Karte mit Angabe des CSPins und  der SPI-Geschwindigkeit starten
     wenn die Intialisierung fehlschlägt
     - keine SD-Karte vorhanden
     - falsche Pinbelegung
     -> es wird eine Fehlermeldung angezeigt
  */
  if (!SD.begin(CSPin, SPI_SPEED)) 
  {
    tft.println("Start der SD-Karte");
    tft.print("fehlgeschlagen!");
    Serial.println("Start der SD-Karte fehlgeschlagen!");
  } 

  else 
  {
    Serial.println("SD-Karte gestartet");
    tft.print("SD-Karte gestartet!");
  }

  delay(5000);
  tft.setTextSize(2);
}

void loop() 
{ 
  reader.drawBMP("koeln.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("K");
    // ö = 0x94
    tft.write(0x94);
    tft.println("ln Blick vom Messeturm");
  }
  
  delay(Intervall); 

  reader.drawBMP("strand.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ);  
    tft.print("Strand Algarve");
  }
  delay(Intervall);
 
  reader.drawBMP("berlin_olympia.bmp", tft, 0, 0);
  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Berlin Olympiastadion");
  }
  delay(Intervall);

  reader.drawBMP("walhalla.bmp", tft, 0, 0);
  if (Beschreibung)
  {  
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Walhalla Donaustauf");
  }

  delay(Intervall);

  reader.drawBMP("dresden_frauenkirche.bmp", tft, 0, 0);

  if (Beschreibung)
  { 
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Dresden Frauenkirche");
  }

  delay(Intervall);

  reader.drawBMP("chartres.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Chartres Dom");
  }

  delay(Intervall);

  reader.drawBMP("gaios.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Gaios Griechenland");
  }

  delay(Intervall);

  reader.drawBMP("braunwald.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 115);  
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Braunwald Schweiz");
  }

  delay(Intervall);

  reader.drawBMP("koeln_deutz.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("K");
    // ö = 0x94
    tft.write(0x94);
    tft.println("ln Deutz");
  }

  delay(Intervall);

  reader.drawBMP("dhuenntalsperre.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 220);  
    tft.fillRect(1, 220, tft.width(), tft.height(), SCHWARZ); 
    tft.print("Dh");
    // ü = 0x81
    tft.write(0x81);
    tft.print("nntalsperre");
  }

  delay(Intervall);
}

Wecker mit Touchscreen

#include "WiFi.h"
#include "time.h"
#include "Adafruit_ILI9341.h"
#include "Fonts/FreeSans9pt7b.h"
#include "Fonts/FreeSans12pt7b.h"
#include "XPT2046_Touchscreen_TT.h"

#define TFT_BL   21
#define TFT_CS   15 
#define TFT_DC    2
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_RST  -1

// Touchscreen SPI-Pins
#define TOUCH_IRQ 36
#define TOUCH_MOSI 32  
#define TOUCH_MISO 39  
#define TOUCH_CLK 25   
#define TOUCH_CS 33

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);

// SPI-Pins als Hardware-SPI
SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(TOUCH_CS, TOUCH_IRQ);

// Variablen Wecker
bool WeckerStatus = false;
int StundeAnzeigen = 6;
int MinuteAnzeigen = 0;
int WeckzeitStunde = 6;
int WeckzeitMinute = 0;

// Pin Lautsprecher
int Lautsprecher = 26; 

// Touchscreen Koordinaten (z = Druck)
int x, y, z;

// WiFi-Daten
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

// Variablen des TFTs (Höhe, Breite, Radius)
const int MitteHoehe = 120;
const int MitteBreite = 120;
const int Radius = 120;

// Multiplikatoren für x- y-Positionen der Stunden, Minuten und Sekunden
float SekundePosX = 0, SekundePosY = 0, MinutePosX = 0, MinutePosY = 0, StundePosX = 0, StundePosY = 0;
float GradSekunden = 0, GradMinuten = 0, GradStunden = 0;

// x- y-Koordinaten für die Anzeige Stunden, Minuten und Sekunden
int SekundenZeigerX = MitteHoehe, SekundenZeigerY = MitteHoehe;
int MinutenZeigerX = MitteHoehe, MinutenZeigerY = MitteHoehe;
int StundenZeigerX = MitteHoehe, StundenZeigerY = MitteHoehe; 

// Start wird nur beim ersten Start für den Aufbau des TFTs benötigt
bool Start = 1;

// Variablen für die Markierungen und Punkte und Striche des Ziffernblatts
float PosX, PosY;
int PunktX, PunktY, PunktX1, PunktX2, PunktY1, PunktY2;

// Variablen für die Zeit
int Stunden, Minuten, Sekunden;

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F
#define ROT         0xF800
#define GRUEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define GELB        0xFFE0
#define BRAUN       0x9A60
#define GRAU        0x7BEF
#define GRUENGELB   0xB7E0
#define DUNKELCYAN  0x03EF
#define ORANGE      0xFDA0
#define PINK        0xFE19
#define BORDEAUX    0xA000
#define HELLBLAU    0x867D
#define VIOLETT     0x915C
#define SILBER      0xC618
#define GOLD        0xFEA0

// Farben innerer Kreis, Randfarbe und Zeigerfarbe
// die Farben der Zeiger können aber auch individuell gesetzt werden
const int Kreisfarbe = SCHWARZ;
const int Zeigerfarbe = WEISS;
const int Randfarbe = BORDEAUX;

// true -> Datum anzeigen
// false -> Datum nicht anzeigen
bool DatumAnzeigen = true;

// true -> Sekundenzeiger nur als Kreis
bool SekundenzeigerKreis = false;

// Ziffern 12 3 6 9 anzeigen/nicht anzeigen
bool Ziffernanzeigen = true;

// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"

/*
  Liste der Zeitzonen
  https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
  CEST = Central European SuMinutener Time von
  M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
  bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"

// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;

/* 
  Struktur tm
  tm_hour -> Stunde: 0 bis 23
  tm_min -> Minuten: 0 bis 59
  tm_sec -> Sekunden 0 bis 59
  tm_mday -> Tag 1 bis 31
  tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
  tm_year -> Jahre seit 1900
  tm_yday -> vergangene Tage seit 1. Januar des Jahres
  tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;

// 1-Bit Canvas definieren, Breite 240, Höhe 80 Pixel
GFXcanvas1 Bereich(240, 80);

unsigned long Zeitmessung = 0;  

void setup() 
{
  Serial.begin(9600);

  // SPI-Bus für den Touchscreen starten
  touchscreenSPI.begin(TOUCH_CLK, TOUCH_MISO, TOUCH_MOSI, TOUCH_CS);
  touchscreen.begin(touchscreenSPI);

  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);

  Serial.println("------------------------");

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(Router);
  Serial.print("IP über DHCP: ");
  Serial.println(WiFi.localIP());

  // Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Zeit in Stunden, Minuten und Sekunden
  Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
  
  // Hintergrundbeleuchtung einschalten
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  tft.begin();
  tft.setRotation(0);

  // wenn die Ausrichtung des Touch-Screens nicht der Ausrichtung des Displays 
  // identisch ist -> Touchscrren drehen
  touchscreen.setRotation(0);

  tft.fillScreen(Kreisfarbe);

  // 4 Pixel breiter äußerer Rand, Farbe au der Farbpalette wählen
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 1, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 2, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 3, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 4, Randfarbe);

  // innere Fläche bis auf den Rand von 4 Pixeln vollständig löschen
  // wenn andere Farbe als äußerer Rand gewählt wird ergibt sich ein schmaler Rand
  tft.fillCircle(MitteHoehe, MitteBreite, Radius - 4, Kreisfarbe);

  /*
    alle 30° Linie am Rand als Stundenmarkierung zeichnen
    DEG_TO_RAD (= PI/180 = 0.0174532925) -> Winkel in Bogenmaß umrechnen
    sin/cos berechnen die x-/y-Kordinaten des Punktes auf der Kreislinie
  */
  for (int i = 0; i < 360; i += 30) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // kurze Linien zeichnen, von 114 bis 100 vom äußeren Rand aus
    // Farbe individuell wählbar
    int PunktX1 = PosX * 110 + Radius;
    int PunktY1 = PosY * 110 + Radius;
    int PunktX2 = PosX * 100 + Radius;
    int PunktY2 = PosY * 100 + Radius;

    // keine Striche an der Position der Zahlen
    if (PunktX1 == 10 || PunktX1 == 120 || PunktX1 == 230)
    {
      tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Kreisfarbe);
    }
    else tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Zeigerfarbe);
  }

  // alle 6 Grad Punkte als Sekundenmarkierung zeichnen
  for (int i = 0; i < 360; i += 6) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // Positionen der Punkte
    // 108 -> Abstand vom Mittelpunkt
    PunktX = PosX * 108 + Radius;
    PunktY = PosY * 108 + Radius;
    tft.drawPixel(PunktX, PunktY, Zeigerfarbe);  
  }

   // Markierung 12 3 6 9
  if (Ziffernanzeigen)
  {
    tft.setFont(&FreeSans9pt7b);
    tft.setTextColor(Zeigerfarbe);
    tft.setCursor(110, 25);
    tft.print("12");

    tft.setCursor(10, 125);
    tft.print("9");

    tft.setCursor(220, 125);
    tft.print("3");
  
    tft.setCursor(113, 230);
    tft.print("6");
  }

  if (DatumAnzeigen) ZeigeDatum();
  
  // linker Button
  tft.setFont(&FreeSans12pt7b);
  tft.fillRect(1, 245, 75, 50, HELLBLAU);
  tft.drawRoundRect(1, 245, 75, 50, 5, SCHWARZ);
  tft.setTextColor(SCHWARZ);
  tft.setCursor(25, 280);
  tft.print(StundeAnzeigen);   

  // mittlerer Button
  tft.fillRect(82, 245, 75, 50, CYAN);
  tft.drawRoundRect(82, 245, 75, 50, 5, SCHWARZ);
  tft.setTextColor(SCHWARZ);
  tft.setCursor(110, 280);
  tft.print(MinuteAnzeigen);
  
  // rechter Button
  tft.fillRect(160, 245, 75, 50, GELB);
  tft.drawRoundRect(160, 245, 75, 50, 5, SCHWARZ);
  tft.setTextColor(SCHWARZ);
  tft.setCursor(180, 280);
  tft.print("aus");  

  Zeitmessung = millis() + 1000; 
}

void loop() 
{
  TouchAbfragen();

  // Sekunden weiter zählen
  if (Zeitmessung < millis()) 
  {
    Zeitmessung += 1000;
    Sekunden++;  

    if (Sekunden == 60) 
    { 
      Sekunden = 0; 
      Minuten++; 

      // Zeit jede Minute mit Zeitserver synchronisieren
      // aktuelle Zeit holen
      time(&aktuelleZeit);

      // localtime_r -> Zeit in die lokale Zeitzone setzen
      localtime_r(&aktuelleZeit, &Zeit);

      // Zeit in Stunden, Minuten und Sekunden
      Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;

      if (Minuten > 59) 
      {
        Minuten = 0;
        Stunden++;  
        if (Stunden > 23) 
        {
          Stunden = 0;
        }
      }
    }

    // Vorausberechnung der x- und y-Koordinaten
    // 0-59 -> 0-354 = Faktor 6
    GradSekunden = Sekunden * 6;    

    // Minuten+Sekunden in Relation zu 3600 setzen
    // 60 / 3600 = 0.01666667         
    GradMinuten = Minuten * 6 + GradSekunden * 0.01666667; 

    // 30 / 3600 = 0.0833333
    // Stunden+Minuten in Relation zu 360 setzen
    // 0-11 -> 0-360 
    GradStunden = Stunden * 30 + GradMinuten * 0.0833333;  // 0-11 -> 0-360 
    StundePosX = cos((GradStunden - 90) * DEG_TO_RAD);
    StundePosY = sin((GradStunden - 90) * DEG_TO_RAD);

    MinutePosX = cos((GradMinuten - 90) * DEG_TO_RAD) ;
    MinutePosY = sin((GradMinuten - 90) * DEG_TO_RAD);

    SekundePosX = cos((GradSekunden - 90) * DEG_TO_RAD);
    SekundePosY = sin((GradSekunden - 90) * DEG_TO_RAD);

    // nach jeder Minute Minuten-/Stundenzeiger löschen
    // oder einmalig beim Start der Anzeige
    if (Sekunden == 0 || Start) 
    {
      Start = false;

      if (DatumAnzeigen) ZeigeDatum();

      tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);  

      // 62 Pixel -> Länge des Stundenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      StundenZeigerX = StundePosX * 62 + MitteHoehe + 1;
      StundenZeigerY = StundePosY * 62 + MitteHoehe + 1;
      tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

      // 84 Pixel -> Länge des Minutenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      MinutenZeigerX = MinutePosX * 84 + MitteHoehe;
      MinutenZeigerY = MinutePosY * 84 + MitteHoehe + 1;
    }

    // Sekundenzeiger löschen
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

    // Kreis am Sekundenzeiger löschen, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, Kreisfarbe);

    // 85 Pixel -> Länge des Sekundenzeigers
    SekundenZeigerX = SekundePosX * 85 + MitteHoehe + 1;
    SekundenZeigerY = SekundePosY * 85 + MitteHoehe + 1;

    // Zeiger neu zeichnen
    // Sekunden Linie nur anzeigen wenn SekundenzeigerKreis false
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, ROT);
    
    // Minuten
    tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Stunden
    tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Kreis an der Spitze des Sekundenzeigers, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, ROT);

    // Mittelpunkt zeichnen
    tft.fillCircle(MitteHoehe, MitteHoehe + 1, 3, Zeigerfarbe); 
  }
}

void ZeigeDatum()
{
  tft.setFont(&FreeSans12pt7b);  
  tft.setCursor(60, 315);
  tft.setTextColor(GRUEN);
      
  // Bildschirmbereich für das Datum löschen
  tft.fillRect(60, 295, 180, 30, SCHWARZ);
  if (Zeit.tm_mday < 10) tft.print("0");
  tft.print(Zeit.tm_mday);
  tft.print(".");

  // Monat: führende 0 ergänzen
  if (Zeit.tm_mon < 9) tft.print("0");
    
  // Zählung beginnt mit 0 -> +1
  tft.print(Zeit.tm_mon + 1);
  tft.print(".");

  // Anzahl Jahre seit 1900
  tft.print(Zeit.tm_year + 1900);
}

void TouchAbfragen()
{
  tft.setFont(&FreeSans12pt7b);

   // wenn der Touchscreen berührt wurde
  if (touchscreen.tirqTouched() && touchscreen.touched()) 
  {
    // Punkte x, y und Druck (z) ermitteln
    TS_Point Punkt = touchscreen.getPoint();

    /*
      die "Rohwerte" der Punkte x und y bewegen sich zwischen 1 und 3800 bzw. 3900
      daher müssen sie mit map auf die korrekten Bildschirmmaße
      korrigiert werden
    */
    x = map(Punkt.x, 240, 3800, 1, tft.width());
    y = map(Punkt.y, 320, 3900, 1, tft.height());
     
    // Rohwerte der Punkte anzeigen
    // Serial.println(Punkt.x);
    // Serial.println(Punkt.y);

    z = Punkt.z;

    // linker Button Koordinaten abfragen
    if (x >= 1 && x <= 75 && y >= 245 && y <= 300) 
    {
      if (StundeAnzeigen == 23) StundeAnzeigen = 0;
      else StundeAnzeigen ++;
      tft.fillRect(1, 245, 75, 50, HELLBLAU);
      tft.drawRoundRect(1, 245, 75, 50, 5, SCHWARZ);
      tft.setTextColor(SCHWARZ);
      tft.setCursor(25, 280);
      tft.print(StundeAnzeigen);   
      WeckzeitStunde = StundeAnzeigen;
    }

    // mittlerer Button Koordinaten abfragen
    if (x >= 85 && x <= 150 && y >= 245 && y <= 300) 
    {
      if (MinuteAnzeigen == 59) MinuteAnzeigen = 0;
      else MinuteAnzeigen ++;
      tft.fillRect(82, 245, 75, 50, CYAN);
      tft.drawRoundRect(82, 245, 75, 50, 5, SCHWARZ);
      tft.setTextColor(SCHWARZ);
      tft.setCursor(110, 280);
      tft.print(MinuteAnzeigen);
      WeckzeitMinute = MinuteAnzeigen;
    }

    // rechter Button Koordinaten abfragen
    if (x >= 165 && x <= 235 && y >= 245 && y <= 300) 
    {
      WeckerStatus = !WeckerStatus;
    }

    // Status des Weckers anzeigen
    if (WeckerStatus) 
    { 
      tft.fillRect(160, 245, 75, 50, GELB);
      tft.drawRoundRect(160, 245, 75, 50, 5, SCHWARZ);
      tft.setTextColor(SCHWARZ);
      tft.setCursor(180, 280);
      tft.print("an");
    }

    else
    {
      tft.fillRect(160, 245, 75, 50, GELB);
      tft.drawRoundRect(160, 245, 75, 50, 5, SCHWARZ);
      tft.setTextColor(SCHWARZ);
      tft.setCursor(180, 280);
      tft.print("aus");      
    }

    // zur Kontrolle die Koordinaten anzeigen
    KoordinatenAnzeigen(x, y, z);
    delay(100);
  }
}

void KoordinatenAnzeigen(int x, int y, int z) 
{
  Serial.print("x-Koordinate = ");
  Serial.print(x);
  Serial.print(" | y-Koordinate = ");
  Serial.print(y);
  Serial.print(" | Druck = ");
  Serial.print(z);
  Serial.println();
}

Letzte Aktualisierung: Juni 17, 2025 @ 11:19