GC9A01 rundes TFT Display mit Arduino ansteuern: Analoge Zifferblätter & Rundinstrumente selbst gestalten

Eckige Displays gibt es überall – aber ein rundes Zifferblatt sieht in jedem Projekt sofort hochwertiger aus. Das GC9A01 TFT-Display ist perfekt kreisrund, hat 240x240 Pixel und lässt sich über SPI genauso einfach ansteuern wie ein rechteckiges Display. In diesem Tutorial baust du eine analoge Uhr mit Sekundenzeiger, ein Rundinstrument (Gauge) für Sensorwerte und ein Menü, das du per Rotary Encoder bedienst.

Was das GC9A01-Display besonders macht

Das 1,28 Zoll GC9A01 Display nutzt einen dedizierten Grafik-Controller-Chip, der wie das verbreitete ST7735 oder ILI9341 über SPI angesprochen wird – der Unterschied liegt einzig in der runden Form und der quadratischen 240x240-Auflösung. Dadurch ist es ideal für alles, was ein klassisches, rundes Ziffernblatt braucht: Analoguhren, Tacho-artige Sensoranzeigen, runde Lautstärkeregler oder Ladezustandsanzeigen.

Da der Controller intern eine vollwertige Grafikbibliothek unterstützt (Linien, Kreise, Text, Bitmaps), lassen sich mit wenigen Zeilen Code komplette Zifferblätter zeichnen – die Adafruit-GFX-kompatible Bibliothek Arduino_GFX bzw. TFT_eSPI übernimmt dabei die komplette Pixel-Ansteuerung.

Was du brauchst

Bauteil Menge ca. Preis Link
1.28 Zoll Rundes TFT LCD Display GC9A01 1x ab 5,99 € Zum Produkt
UNO R3 Entwicklungsboard 1x ab 4,99 € Zum Produkt
DS3231 Echtzeituhr-Modul (für die Analoguhr) 1x ab 2,99 € Zum Produkt
Rotary Encoder KY-040 (für die Menüsteuerung) 1x ab 2,79 € Zum Produkt
Breadboard 400 Kontakte 1x ab 3,49 € Zum Produkt

Schaltungsaufbau

GC9A01 Pin UNO R3 Pin Funktion
VCC 5V Spannungsversorgung
GND GND Masse
SCL (SCK) Pin 13 SPI-Takt
SDA (MOSI) Pin 11 SPI-Daten
RES Pin 8 Reset
DC Pin 9 Daten/Befehl-Umschaltung
CS Pin 10 Chip Select
BLK 5V (oder PWM-Pin für Dimmen) Hintergrundbeleuchtung

Für den DS3231 (I2C) verbindest du zusätzlich SDA mit A4 und SCL mit A5 sowie VCC mit 5V und GND mit GND. Der Rotary Encoder benötigt zwei digitale Pins für CLK/DT (z. B. Pin 2 und 3) sowie einen für den Taster (z. B. Pin 4).

Code 1: Grundgerüst & Kreis-Zifferblatt zeichnen

Installiere über den Bibliotheksverwalter Arduino_GFX_Library von moononournation, die den GC9A01-Treiber direkt mitbringt. Dieser erste Sketch zeichnet ein rundes Zifferblatt mit Stundenmarkierungen.

#include <Arduino_GFX_Library.h>

#define TFT_CS   10
#define TFT_DC    9
#define TFT_RST   8

Arduino_DataBus *bus = new Arduino_HWSPI(TFT_DC, TFT_CS);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RST, 0 /* rotation */, true /* IPS */);

const int MITTE_X = 120;
const int MITTE_Y = 120;
const int RADIUS = 110;

void zeichneZifferblatt() {
  gfx->fillScreen(BLACK);
  gfx->drawCircle(MITTE_X, MITTE_Y, RADIUS, WHITE);

  for (int i = 0; i < 12; i++) {
    float winkel = i * 30 * PI / 180.0;
    int x1 = MITTE_X + (RADIUS - 15) * sin(winkel);
    int y1 = MITTE_Y - (RADIUS - 15) * cos(winkel);
    int x2 = MITTE_X + RADIUS * sin(winkel);
    int y2 = MITTE_Y - RADIUS * cos(winkel);
    gfx->drawLine(x1, y1, x2, y2, WHITE);
  }
}

void setup() {
  gfx->begin();
  zeichneZifferblatt();
}

void loop() {
}

Die Trigonometrie mit sin()/cos() berechnet für jede der 12 Stunden-Positionen einen Punkt auf dem Kreisrand – dieses Grundprinzip nutzt du gleich für die Zeiger und später für das Gauge-Instrument wieder.

Code 2: Analoguhr mit DS3231 Echtzeituhr

Jetzt ergänzt du bewegliche Zeiger, deren Winkel aus der aktuellen Uhrzeit des DS3231-Moduls berechnet werden.

#include <Arduino_GFX_Library.h>
#include <Wire.h>
#include <RTClib.h>

#define TFT_CS   10
#define TFT_DC    9
#define TFT_RST   8

Arduino_DataBus *bus = new Arduino_HWSPI(TFT_DC, TFT_CS);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RST, 0, true);
RTC_DS3231 rtc;

const int MITTE_X = 120;
const int MITTE_Y = 120;

void zeichneZeiger(int stunde, int minute, int sekunde) {
  gfx->fillScreen(BLACK);
  gfx->drawCircle(MITTE_X, MITTE_Y, 110, WHITE);

  float sekWinkel = sekunde * 6 * PI / 180.0;
  float minWinkel = (minute * 6 + sekunde * 0.1) * PI / 180.0;
  float stdWinkel = ((stunde % 12) * 30 + minute * 0.5) * PI / 180.0;

  int sx = MITTE_X + 95 * sin(sekWinkel);
  int sy = MITTE_Y - 95 * cos(sekWinkel);
  gfx->drawLine(MITTE_X, MITTE_Y, sx, sy, RED);

  int mx = MITTE_X + 80 * sin(minWinkel);
  int my = MITTE_Y - 80 * cos(minWinkel);
  gfx->drawLine(MITTE_X, MITTE_Y, mx, my, WHITE);

  int hx = MITTE_X + 55 * sin(stdWinkel);
  int hy = MITTE_Y - 55 * cos(stdWinkel);
  gfx->drawLine(MITTE_X, MITTE_Y, hx, hy, WHITE);
}

void setup() {
  gfx->begin();
  rtc.begin();
  // Einmalig zum Stellen der Uhrzeit auskommentieren:
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
  DateTime jetzt = rtc.now();
  zeichneZeiger(jetzt.hour(), jetzt.minute(), jetzt.second());
  delay(1000);
}

⚠️ Flackern reduzieren: Dieser einfache Sketch löscht den kompletten Bildschirm bei jedem Sekundentick, was auf Dauer flackert. Für eine ruckelfreie Anzeige zeichnest du die alten Zeiger in Schwarz nach (überschreiben statt löschen) oder nutzt einen Sprite-Puffer, den Arduino_GFX ebenfalls unterstützt.

Code 3: Rundinstrument (Gauge) für Sensorwerte

Statt einer Uhr eignet sich das runde Display genauso gut als Tacho-artige Anzeige, z. B. für einen Temperaturwert von 0-100°C, dargestellt als Bogen von -135° bis +135°.

#include <Arduino_GFX_Library.h>

#define TFT_CS   10
#define TFT_DC    9
#define TFT_RST   8

Arduino_DataBus *bus = new Arduino_HWSPI(TFT_DC, TFT_CS);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RST, 0, true);

const int MITTE_X = 120;
const int MITTE_Y = 120;
const float START_WINKEL = -135;
const float END_WINKEL = 135;

void zeichneGauge(float wert, float minWert, float maxWert) {
  gfx->fillScreen(BLACK);
  gfx->drawCircle(MITTE_X, MITTE_Y, 110, WHITE);

  // Skala als Bogen aus einzelnen Strichen
  for (float w = START_WINKEL; w <= END_WINKEL; w += 15) {
    float rad = w * PI / 180.0;
    int x1 = MITTE_X + 95 * sin(rad);
    int y1 = MITTE_Y - 95 * cos(rad);
    int x2 = MITTE_X + 105 * sin(rad);
    int y2 = MITTE_Y - 105 * cos(rad);
    gfx->drawLine(x1, y1, x2, y2, WHITE);
  }

  // Zeiger entsprechend dem aktuellen Wert
  float anteil = (wert - minWert) / (maxWert - minWert);
  float zeigerWinkel = START_WINKEL + anteil * (END_WINKEL - START_WINKEL);
  float rad = zeigerWinkel * PI / 180.0;
  int zx = MITTE_X + 80 * sin(rad);
  int zy = MITTE_Y - 80 * cos(rad);
  gfx->drawLine(MITTE_X, MITTE_Y, zx, zy, RED);

  gfx->setCursor(90, 160);
  gfx->setTextColor(WHITE);
  gfx->setTextSize(2);
  gfx->print(wert, 1);
}

void setup() {
  gfx->begin();
}

void loop() {
  float simulierterWert = 20 + 15 * sin(millis() / 2000.0);
  zeichneGauge(simulierterWert, 0, 40);
  delay(200);
}

Ersetze den simulierterWert in loop() durch einen echten Sensorwert – etwa von unserem BMP280-Luftdrucksensor oder DHT22 –, um ein individuelles Analog-Instrument für dein Wetterstation- oder Monitoring-Projekt zu bauen.

Praxistipps

🎨 Rotation beachten: Der dritte Parameter im Arduino_GC9A01-Konstruktor legt die Bilddrehung fest (0-3). Da das Display rund ist, spielt die Rotation nur eine Rolle, wenn du Text darstellst – probiere alle vier Werte durch, falls Text auf dem Kopf steht.

⚡ Hintergrundbeleuchtung dimmen: Verbinde BLK statt fest mit 5V mit einem PWM-fähigen Pin und steuere die Helligkeit per analogWrite() – praktisch für ein Display, das nachts automatisch dunkler werden soll.

🔄 Menüsteuerung ergänzen: Kombiniere das Display mit unserem Rotary-Encoder-Tutorial, um zwischen mehreren Anzeigemodi (Uhr, Gauge, Statusbildschirm) durchzuschalten.

Troubleshooting

⚠️ Display bleibt schwarz: Prüfe zuerst BLK (Hintergrundbeleuchtung) – ist dieser Pin nicht mit 5V verbunden, bleibt der Bildschirm dunkel, obwohl die Software korrekt läuft. Danach RES/DC/CS auf korrekte Pinbelegung im Code kontrollieren.

⚠️ Verzerrte oder verschobene Grafik: Meist ein falscher Rotationswert oder eine falsche IPS-Einstellung im Konstruktor. Teste systematisch die Werte 0-3 für die Rotation.

⚠️ DS3231 zeigt falsche Zeit nach Stromausfall: Ohne Pufferbatterie (CR2032) auf dem Modul geht die Zeit bei Stromverlust verloren. Prüfe, ob eine Batterie eingelegt ist, und stelle die Uhrzeit nach dem ersten Flashen einmal über rtc.adjust().

🕐 Baue dein rundes Anzeige-Projekt

Alle Bauteile für dieses Tutorial findest du bei MAKEROO.

Für eine eckige Alternative mit Touch-Bedienung schau dir unser OLED SSD1306 Tutorial an.

Fazit

Das GC9A01-Display bringt mit seiner runden Form einen echten Wow-Effekt in jedes Arduino-Projekt. Ob klassische Analoguhr mit Echtzeituhr-Anbindung oder ein Tacho-artiges Gauge für Sensordaten – mit der Arduino_GFX-Bibliothek und etwas Trigonometrie gestaltest du in kurzer Zeit ein individuelles, rundes Zifferblatt für deine eigenen Projekte.

Zurück zum Blog