OLED Display SSD1306 mit Arduino – Text, Grafiken und Animationen darstellen
Kompakte OLED-Displays mit dem SSD1306-Chip sind der perfekte Einstieg in die Welt der grafischen Ausgaben am Arduino. Ob Text, gezeichnete Formen, animierte Ladebalken oder ein Live-Sensor-Dashboard – das 128×64 Pixel große Display bringt deine Projekte auf ein neues Level. In diesem Tutorial zeigen wir dir Schritt für Schritt, wie du das 0,96" SSD1306-OLED mit deinem Arduino UNO oder Nano verbindest, die wichtigsten Bibliotheken einrichtest und mit fünf lauffähigen Code-Beispielen direkt loslegen kannst.
Warum ein OLED-Display mit SSD1306?
OLED steht für Organic Light Emitting Diode – jeder Pixel leuchtet selbst, eine Hintergrundbeleuchtung ist nicht nötig. Das bringt zwei entscheidende Vorteile: satte Kontraste mit tiefem Schwarz und einen extrem niedrigen Stromverbrauch. Im ausgeschalteten Zustand verbraucht das Display nahezu nichts, und selbst bei voller Darstellung liegt der Verbrauch meist unter 20 mA.
Der SSD1306 ist der Controller-Chip, der die eigentliche Display-Ansteuerung übernimmt. Er verwaltet einen internen GDDRAM-Speicher (Graphics Display Data RAM) von 128 × 64 Bit – das entspricht exakt 1024 Bytes, also einem Bit pro Pixel. Der Chip unterstützt mehrere serielle Schnittstellen: I²C, 3-Wire- und 4-Wire-SPI sowie 8-Bit-Parallel. Die mit Abstand beliebteste Variante im Maker-Bereich ist I²C, weil sie nur zwei Datenleitungen benötigt.
Das Wichtigste auf einen Blick: Das 0,96" SSD1306-OLED bietet 128×64 Pixel Auflösung, monochrom (nur eine Farbe – meist Weiß oder Blau), Ansteuerung über I²C mit nur 4 Kabeln und ist für unter 5 € ein unschlagbares Einsteiger-Display. Perfekt für Sensorwerte, Status-Anzeigen, Mini-Menüs oder Retro-Pixel-Animationen.
🖥️ 0.96" OLED Display SSD1306 (I²C)
- 128×64 Pixel Auflösung
- I²C-Schnittstelle (nur 4 Pins: VCC, GND, SCL, SDA)
- Betriebsspannung: 3,3 V – 5 V
- Anzeigefarbe: Weiß
- Betrachtungswinkel: >160°
- Abmessungen: ca. 27 mm × 27 mm
👉 Im makeroo-Shop: OLED Display 0.96" SSD1306 ansehen
Technischer Tiefgang: I²C, SSD1306-Controller & Grafik-Buffer
Das I²C-Protokoll verstehen
I²C (Inter-Integrated Circuit, gesprochen „I-Quadrat-C") ist ein serieller Bus, der mit nur zwei Leitungen mehrere Geräte verbindet: SDA (Serial Data) und SCL (Serial Clock). Der Arduino fungiert als Master, das Display als Slave. Jedes I²C-Gerät besitzt eine 7-Bit-Adresse – beim SSD1306 ist das meist 0x3C. Manche Module haben durch einen Jumper auf der Rückseite die Adresse 0x3D.
| Pin am Display | Pin am Arduino UNO | Funktion |
|---|---|---|
| VCC | 5V (oder 3.3V) | Spannungsversorgung |
| GND | GND | Masse |
| SCL | A5 (bzw. SCL) | I²C Clock (Taktleitung) |
| SDA | A4 (bzw. SDA) | I²C Data (Datenleitung) |
Hinweis für Arduino UNO R3 und Nano: Bei beiden Boards sind die I²C-Pins fest auf A4 (SDA) und A5 (SCL) gelegt. Du kannst sie direkt mit den entsprechenden Pins des OLED-Moduls verbinden. Beim Arduino Mega liegen SDA und SCL auf Pin 20 und 21.
SSD1306-Controller & GDDRAM
Der SSD1306-Controller von Solomon Systech ist das Gehirn des Displays. Sein zentrales Element ist der GDDRAM – ein 1024 Byte großer Videospeicher, der exakt 128 × 64 Bit abbildet (128 × 64 / 8 = 1024 Bytes). Jedes Bit entspricht einem Pixel: 1 = an, 0 = aus. Der Controller teilt den Speicher in 8 horizontale Pages zu je 128 Bytes – das ist der Grund, warum viele Grafikbibliotheken seitenweise aktualisieren.
Die Adafruit-Bibliotheken kapseln dieses Verhalten: Sie halten einen Framebuffer im RAM des Arduino (ebenfalls 1024 Bytes), zeichnen darauf und übertragen ihn bei display.display() in einem Rutsch per I²C an das Display. Das ist effizient, kostet aber selbst beim Arduino UNO nur 1024 der 2048 Bytes SRAM – also die Hälfte des verfügbaren Arbeitsspeichers. Für die meisten Projekte ist das völlig ausreichend.
Schriftarten: Glcd, FreeFonts & Performance
Die Standardbibliothek bringt die Glcd-Schriftart mit – eine einfache 5×7-Pixel-Monospace-Schrift für grundlegende Textausgaben. Für ansprechendere Darstellungen kannst du über die Adafruit_GFX-Bibliothek FreeFonts einbinden, die aus TrueType-Schriften konvertierte Bitmaps nutzen. Der Nachteil: Sie belegen deutlich mehr Flash-Speicher und reduzieren die darstellbaren Zeichen pro Zeile.
Für deutsche Umlaute (ä, ö, ü, ß) brauchst du einen Workaround, da die Standardschriftarten nur den ASCII-Zeichensatz (0–127) unterstützen. Entweder ersetzt du Umlaute durch ae/oe/ue/ss, oder du nutzt benutzerdefinierte Zeichensätze.
FPS-Limitierungen bei I²C
I²C im Standard-Mode läuft mit 100 kHz, im Fast-Mode mit 400 kHz. Die Übertragung eines kompletten Frames (1024 Bytes) dauert selbst bei 400 kHz rund 20–25 ms. Hinzu kommt die Render-Zeit auf dem Arduino für komplexe Grafiken. Daraus ergibt sich ein realistisches Limit von etwa 25–35 FPS – für flüssige Text-Scrolling und einfache Animationen völlig ausreichend, für Videos oder Spielgrafik aber ungeeignet. Plane deine Animationen entsprechend: Weniger als 30 ms pro Frame solltest du nicht unterschreiten.
Hardware-Aufbau & Verkabelung
Benötigte Komponenten
0.96" OLED Display SSD1306 (I²C)
Das Herzstück des Projekts. 128×64 Pixel, weiß, I²C-Schnittstelle. Zum Produkt →
Arduino UNO R3
Das bewährte Einstiegsboard mit ATmega328P, 14 digitalen I/O-Pins und nativer I²C-Unterstützung. Zum Produkt →
Breadboard 400
Steckbrett für den schnellen, lötfreien Aufbau. Zum Produkt →
JST-XH Stecker Set
Für saubere Kabelverbindungen vor allem bei festen Einbauprojekten. Zum Produkt →
Schaltplan textuell
Die Verkabelung ist denkbar einfach – du brauchst nur vier Kabel (Male-to-Female Jumper Wire):
- VCC am OLED → 5V am Arduino UNO
- GND am OLED → GND am Arduino UNO
- SCL am OLED → A5 (SCL) am Arduino UNO
- SDA am OLED → A4 (SDA) am Arduino UNO
Vorsicht vor Vertauschen: Vertauschte VCC- und GND-Verbindungen können das OLED-Modul dauerhaft zerstören. Prüfe vor dem Einschalten noch einmal sorgfältig alle Verbindungen. Ein verpoltes Display ist ein totes Display.
Die meisten SSD1306-Module haben die Pin-Beschriftung direkt auf der Rückseite aufgedruckt. Bei einigen Boards findest du auch Jumper zum Umschalten der I²C-Adresse zwischen 0x3C und 0x3D – lass den Jumper zunächst auf der Standardposition.
Bibliotheken installieren
Für die Code-Beispiele benötigst du zwei Bibliotheken aus dem Arduino Library Manager:
- 1 Adafruit SSD1306 – Treiber für den SSD1306-Controller
- 2 Adafruit GFX Library – Grafikbasis (Schriften, Formen, Bitmaps)
Öffne dazu die Arduino IDE, gehe auf Werkzeuge → Bibliotheken verwalten, suche nach SSD1306 und installiere die aktuelle Version von „Adafruit SSD1306" (die Abhängigkeit „Adafruit GFX Library" wird automatisch mit installiert).
Für das Sensor-Beispiel in Abschnitt 4 brauchst du zusätzlich die Adafruit BME280 Library. Installiere sie auf dem gleichen Weg.
I²C-Scanner als erster Test: Bevor du mit den Grafiken loslegst, lohnt sich ein kurzer I²C-Adress-Scan. Der Arduino I²C-Scanner (unter Datei → Beispiele → Wire → i2c_scanner) zeigt dir an, ob und unter welcher Adresse das Display gefunden wird. Erscheint 0x3C im seriellen Monitor, ist alles korrekt verkabelt.
Beispiel 1: Hello World & Textformatierung
Das erste Programm zeigt die grundlegende Initialisierung des Displays und verschiedene Textfunktionen: Schriftgröße, Farbe, Cursor-Positionierung und dynamische Werte.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
// Display initialisieren
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("SSD1306 nicht gefunden!");
while (true);
}
display.clearDisplay();
// Textgröße 1 (Default: 6×8 Pixel pro Zeichen)
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("makeroo.de");
display.println("OLED Tutorial");
// Textgröße 2 (doppelte Größe)
display.setTextSize(2);
display.setCursor(0, 28);
display.println("Hello");
// Dynamischer Wert
display.setTextSize(1);
display.setCursor(0, 56);
display.print("Millis: ");
display.print(millis() / 1000);
display.print(" s");
display.display();
}
void loop() {
// Live-Zähler aktualisieren
display.fillRect(60, 56, 68, 8, SSD1306_BLACK);
display.setCursor(60, 56);
display.print(millis() / 1000);
display.display();
delay(100);
}
Dieses Beispiel demonstriert die Kernfunktionen: setTextSize() skaliert die Schrift, setCursor(x, y) positioniert den Text, und fillRect() löscht einen Bereich gezielt – effizienter als ein clearDisplay() des gesamten Bildschirms, weil nur der geänderte Bereich aktualisiert wird.
Beispiel 2: Grafiken zeichnen – Linien, Kreise & Rechtecke
Die Adafruit GFX Library bietet eine Vielzahl von Zeichenfunktionen. Dieses Beispiel zeichnet geometrische Formen und demonstriert die wichtigsten Funktionen.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
// --- Gefülltes Rechteck (Hintergrund-Banner) ---
display.fillRect(0, 0, 128, 14, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setTextSize(1);
display.setCursor(4, 3);
display.println("makeroo Grafiktutorial");
display.setTextColor(SSD1306_WHITE);
// --- Linien ---
display.drawLine(0, 20, 127, 20, SSD1306_WHITE); // horizontal
display.drawLine(64, 18, 64, 63, SSD1306_WHITE); // vertikal
// --- Leeres Rechteck ---
display.drawRect(5, 25, 54, 18, SSD1306_WHITE);
// --- Gefülltes Rechteck ---
display.fillRect(5, 25, 54, 18, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setCursor(10, 30);
display.println("fillRect");
display.setTextColor(SSD1306_WHITE);
// --- Kreise ---
display.drawCircle(95, 44, 15, SSD1306_WHITE); // leerer Kreis
display.fillCircle(78, 52, 6, SSD1306_WHITE); // gefüllter Kreis
// --- Abgerundetes Rechteck ---
display.drawRoundRect(2, 46, 26, 16, 4, SSD1306_WHITE);
// --- Dreieck ---
display.drawTriangle(100, 18, 115, 30, 85, 30, SSD1306_WHITE);
display.fillTriangle(95, 60, 105, 50, 115, 60, SSD1306_WHITE);
display.display();
}
void loop() { }
Die Farben SSD1306_WHITE (Pixel an) und SSD1306_BLACK (Pixel aus, Hintergrund) erlauben dir, mit negativ- und positiv-Darstellung zu arbeiten. Das Beispiel macht davon Gebrauch: Ein weißes Banner mit schwarzem Text obendrauf erzeugt einen professionellen Look.
Beispiel 3: Animierte Bitmaps & Ladeanimation
Das Zeichnen eigener Bitmaps gibt dir volle Kontrolle über die Darstellung. In diesem Beispiel erstellen wir ein animiertes WLAN-Symbol und einen Fortschrittsbalken – zwei Klassiker für Status-Displays.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// WLAN-Symbol als Bitmap (16×16 Pixel)
const uint8_t wifi_icon[] PROGMEM = {
0x00, 0x00, 0x07, 0xE0, 0x1F, 0xF8, 0x3C, 0x1C,
0x73, 0xCE, 0x07, 0xE0, 0x1E, 0x78, 0x00, 0x00,
0x01, 0x80, 0x07, 0xE0, 0x00, 0x00, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00
};
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
}
void loop() {
// --- Animation 1: Ladebalken ---
for (int i = 0; i <= 100; i += 5) {
display.clearDisplay();
// Überschrift
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ladevorgang...");
// Prozent
display.setTextSize(2);
display.setCursor(42, 15);
display.print(i);
display.println("%");
// Fortschrittsbalken (100px breit, 10px hoch)
display.drawRect(14, 40, 100, 10, SSD1306_WHITE);
int barWidth = map(i, 0, 100, 0, 98);
display.fillRect(15, 41, barWidth, 8, SSD1306_WHITE);
display.display();
delay(80);
}
delay(500);
// --- Animation 2: WLAN-Symbol pulsierend ---
for (int s = 0; s < 3; s++) {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Verbunden!");
// WLAN-Icon in wechselnder Position zeichnen
int x = 56 + s * 8;
display.drawBitmap(x, 28, wifi_icon, 16, 16, SSD1306_WHITE);
display.display();
delay(400);
}
delay(1000);
}
Bitmaps selbst erstellen: Online-Tools wie image2cpp (javl.github.io/image2cpp) wandeln PNGs direkt in C-Arrays um. Einfach Bild hochladen, auf 128×64 (oder kleiner) zuschneiden, „Arduino Code" als Ausgabeformat wählen und das generierte Array in deinen Sketch kopieren. Wichtig: Das Array mit PROGMEM deklarieren, damit es im Flash-Speicher landet und nicht den knappen RAM belegt.
Beispiel 4: Sensor-Dashboard mit BME280
Jetzt wird es praktisch: Ein Live-Dashboard, das Temperatur, Luftfeuchtigkeit und Luftdruck des BME280-Sensors ausliest und übersichtlich darstellt. Der BME280 ist ein hochpräziser Kombi-Sensor von Bosch, der über I²C angesprochen wird – perfekt für Umweltmessungen.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BME280.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_BME280 bme;
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
// BME280 initialisieren (Standard-I²C-Adresse 0x76)
if (!bme.begin(0x76)) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("BME280 nicht");
display.println("gefunden!");
display.display();
while (true);
}
display.clearDisplay();
}
void loop() {
// Werte auslesen
float temp = bme.readTemperature();
float hum = bme.readHumidity();
float pres = bme.readPressure() / 100.0F;
display.clearDisplay();
// === Dashboard-Header ===
display.fillRect(0, 0, 128, 12, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setTextSize(1);
display.setCursor(2, 2);
display.println("makeroo Sensor-Dashboard");
display.setTextColor(SSD1306_WHITE);
// === Temperatur ===
display.setTextSize(2);
display.setCursor(0, 16);
display.print(temp, 1);
display.print((char)247); // Grad-Zeichen
display.println("C");
// === Luftfeuchtigkeit ===
display.setCursor(0, 36);
display.print(hum, 0);
display.println("% rH");
// === Luftdruck ===
display.setTextSize(1);
display.setCursor(0, 56);
display.print("Druck: ");
display.print(pres, 1);
display.println(" hPa");
// === Mini-Balken für Luftfeuchtigkeit ===
int barH = map((int)hum, 0, 100, 0, 48);
display.fillRect(90, 14, 36, 48, SSD1306_BLACK); // alten Balken löschen
display.drawRect(90, 14, 36, 48, SSD1306_WHITE); // Rahmen
display.fillRect(91, 14 + (48 - barH), 34, barH, SSD1306_WHITE); // Füllung
display.display();
delay(2000);
}
Das Dashboard kombiniert mehrere Techniken: Headergrafik mit invertierten Farben, zweizeilige Werteausgabe in großer Schrift und eine visuelle Feuchtigkeitsanzeige als senkrechter Balken. Der map()-Befehl skaliert den Prozentwert auf die verfügbaren 48 Pixel Höhe.
🌡️ BME280 Umwelt-Sensor (I²C)
- Temperatur, Luftfeuchtigkeit & Luftdruck in einem Modul
- I²C-Schnittstelle – parallel zum OLED betreibbar
- Hohe Genauigkeit: ±0,5 °C, ±3 % rH, ±1 hPa
- Betriebsspannung: 3,3 V (5 V-tolerante I²C-Pins)
👉 Im makeroo-Shop: BME280 Sensor ansehen
Beispiel 5 (optional): Micro-Menü mit Rotary Encoder
Für fortgeschrittene Projekte mit Nutzerinteraktion zeigt dieses Beispiel ein kleines Auswahlmenü, das per Rotary Encoder bedient wird. Ideal für Geräte mit mehreren Funktionen oder Einstellungen.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
#define ENC_CLK 2 // Encoder Clock (Interrupt-Pin)
#define ENC_DT 3 // Encoder Data
#define ENC_SW 4 // Encoder Button
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const char* menuItems[] = {
"Temperatur",
"Luftfeuchte",
"Uhrzeit",
"Einstellungen",
"Info"
};
const int menuCount = 5;
int selectedItem = 0;
int lastEncoded = 0;
volatile int encoderPos = 0;
void setup() {
pinMode(ENC_CLK, INPUT_PULLUP);
pinMode(ENC_DT, INPUT_PULLUP);
pinMode(ENC_SW, INPUT_PULLUP);
// Encoder-Interrupt
attachInterrupt(digitalPinToInterrupt(ENC_CLK), readEncoder, CHANGE);
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
drawMenu();
}
void loop() {
// Encoder-Position auswerten
if (encoderPos != lastEncoded) {
if (encoderPos > lastEncoded) {
selectedItem = (selectedItem + 1) % menuCount;
} else {
selectedItem = (selectedItem - 1 + menuCount) % menuCount;
}
lastEncoded = encoderPos;
drawMenu();
}
// Button-Auswahl
if (digitalRead(ENC_SW) == LOW) {
delay(50); // Entprellen
if (digitalRead(ENC_SW) == LOW) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
display.print(menuItems[selectedItem]);
display.setCursor(10, 40);
display.print("ausgewahlt!");
display.display();
delay(1500);
drawMenu();
}
}
delay(5);
}
void drawMenu() {
display.clearDisplay();
// Header
display.fillRect(0, 0, 128, 12, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setTextSize(1);
display.setCursor(2, 2);
display.println("makeroo Menu");
display.setTextColor(SSD1306_WHITE);
// Menü-Einträge (max 4 sichtbar)
int firstVisible = constrain(
selectedItem - 1, 0, menuCount - 4);
for (int i = 0; i < 4; i++) {
int idx = firstVisible + i;
if (idx >= menuCount) break;
int y = 16 + i * 12;
if (idx == selectedItem) {
// Ausgewähltes Item: invertiert
display.fillRect(0, y - 1, 128, 11, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
} else {
display.setTextColor(SSD1306_WHITE);
}
display.setCursor(16, y);
display.println(menuItems[idx]);
}
display.display();
}
void readEncoder() {
int MSB = digitalRead(ENC_CLK);
int LSB = digitalRead(ENC_DT);
int encoded = (MSB << 1) | LSB;
int sum = (lastEncoded << 2) | encoded;
if (sum == 0b1101 || sum == 0b0100 ||
sum == 0b0010 || sum == 0b1011) {
encoderPos++;
}
if (sum == 0b1110 || sum == 0b0111 ||
sum == 0b0001 || sum == 0b1000) {
encoderPos--;
}
}
Das Menü nutzt einen Interrupt am Encoder-Clock-Pin, um Drehungen zuverlässig zu erfassen – selbst bei schnellem Drehen gehen keine Schritte verloren. Die aktuelle Auswahl wird durch invertierte Darstellung (weißer Balken mit schwarzem Text) hervorgehoben, und ein Scroll-Mechanismus sorgt dafür, dass auch Menüs mit mehr als 4 Einträgen bedienbar bleiben.
Erweiterungsidee: Ersetze den Platzhalter-Button-Handler durch reale Funktionen – z. B. ein Untermenü für Einstellungen, Sensorwert-Anzeigen wie in Beispiel 4 oder eine Status-Seite. Mit dem 1.3" OLED und integriertem Encoder (im Shop ansehen) hast du beides bereits auf einem kompakten Board vereint.
I²C-Adressen im Überblick
Wenn du mehrere I²C-Geräte am gleichen Bus betreibst – z. B. SSD1306-Display und BME280-Sensor – müssen ihre Adressen unterschiedlich sein. Hier die gängigsten Werte:
| Gerät | Standard-Adresse | Alternative Adresse | Umstellung |
|---|---|---|---|
| SSD1306 OLED (0.96") | 0x3C | 0x3D | Jumper auf Modul-Rückseite |
| SSD1306 OLED (1.3") | 0x3C | 0x3D | Jumper auf Modul-Rückseite |
| BME280 | 0x76 | 0x77 | SDO-Pin (LOW = 0x76, HIGH = 0x77) |
| PCF8574 I/O-Expander | 0x20 | 0x21–0x27 | A0/A1/A2-Adresspins |
Display bleibt schwarz? Die häufigste Ursache ist eine falsche I²C-Adresse im Code. Teste zuerst mit dem I²C-Scanner-Sketch, welche Adresse dein Display tatsächlich verwendet. Der zweithäufigste Fehler: SCL und SDA vertauscht.
Praxis-Tipps für den Alltag
Display-Lebensdauer & Burn-in
OLEDs können bei statischen Bildern mit der Zeit einbrennen (Burn-in). Das ist bei den kleinen monochromen Displays weniger dramatisch als bei Smartphone-AMOLEDs, aber dennoch ein Thema bei Dauerbetrieb. Gegenmaßnahmen: Bildschirm nachts per display.ssd1306_command(SSD1306_DISPLAYOFF) ausschalten, regelmäßig den Inhalt leicht verschieben, oder einen Screensaver mit bewegten Elementen programmieren.
Stromsparen im Batteriebetrieb
Für batteriebetriebene Projekte: display.dim(true) reduziert die Helligkeit und senkt den Verbrauch um etwa 30–40 %. Im Sleep-Modus (SSD1306_DISPLAYOFF) sinkt der Verbrauch auf unter 5 µA – erst dann ist das System wirklich sparsam. Vergiss nicht, auch den Arduino in den Sleep-Modus zu versetzen (<LowPower.h>), sonst frisst der Mikrocontroller mehr als das Display.
Display drehen & spiegeln
Manchmal passt die physische Ausrichtung des Displays nicht zur gewünschten Darstellung. Mit display.setRotation(2) kannst du den Bildschirm um 180° drehen. Werte: 0 (Standard), 1 (90°), 2 (180°), 3 (270°). Beachte, dass bei Rotation die Koordinaten entsprechend verschoben werden.
Mehrere I²C-Displays parallel
Zwei identische SSD1306 an einem Bus? Kein Problem, wenn die Module unterschiedliche Adressen haben (0x3C und 0x3D, per Jumper einstellbar). Du legst dann einfach zwei Display-Objekte an und sprichst sie getrennt an. Jedes braucht seinen eigenen Framebuffer – das kostet 2×1024 Bytes = 2048 Bytes RAM, was das UNO gerade noch mitmacht.
Bereit für dein OLED-Projekt?
Alles, was du für den Start brauchst, findest du bei makeroo – vom SSD1306 OLED-Display über den Arduino UNO R3 oder Arduino Nano V3 bis zu Sensoren wie dem BME280. Dazu Breadboards und Steckverbinder für den sauberen Aufbau.
Alle Code-Beispiele sind getestet und laufen direkt nach dem Kopieren in die Arduino IDE. Du hast Fragen oder ein Projekt, bei dem du nicht weiterkommst? Schreib uns – wir helfen gern!
Fazit: Warum das SSD1306 dein nächstes Projekt verdient
Das 0,96" SSD1306-OLED ist weit mehr als ein „Hello World"-Display. Mit 128×64 Pixeln, einfacher I²C-Anbindung und einer exzellenten Bibliotheks-Unterstützung durch Adafruit hast du in weniger als 10 Minuten ein vollwertiges Grafikdisplay am Laufen. Die fünf Beispiele in diesem Tutorial decken die gesamte Bandbreite ab – von der simplen Textausgabe über selbst gezeichnete Grafiken und Bitmap-Animationen bis zum interaktiven Menü und Live-Sensor-Dashboard.
Gerade für IoT-Projekte, Wetterstationen, Status-Anzeigen oder Benutzeroberflächen in eigenen Geräten ist das SSD1306 die erste Wahl. Der Preis von rund 4–5 € macht es zudem zu einem der günstigsten grafischen Displays auf dem Markt – und das bei OLED-typischer Bildqualität, die selbst teurere LC-Displays alt aussehen lässt.
Jetzt bist du dran: Schnapp dir ein Display, kopiere den Code und leg los. Und wenn du weitere Sensoren, Mikrocontroller oder Zubehör brauchst – du weißt ja, wo du sie findest. 🦉