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.
- Anzeige- & Ausgabekomponenten – Displays in vielen Formaten
- Mikrocontroller-Boards – UNO R3, Nano V3 und ESP32
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.