Lopaka Basics 05: Vom Browser zum Board

Du hast einen Screen gezeichnet, du hast den Code hochgeladen, und das Display bleibt schwarz. Das Display ist selten kaputt. Meist ist es eines von fünf Dingen, und sobald du das richtige behebst, leuchtet der Screen auf.
In dieser Episode bringst du das Morgen-Dashboard aus Episode 2 vom Browser auf ein Board: Installiere die Bibliothek in der Arduino IDE, baue den Sketch um den Code von Lopaka und prüfe, wie viel Speicher er nutzt. Dann gehst du die fünf Gründe durch, warum ein neues Display schwarz bleibt, und die Behebung für jeden.
Was du bauen wirst: einen Arduino-Sketch, der die Screens Morning und Night aus Episode 2 auf einem 128×64-SSD1306-OLED zeigt, plus eine Checkliste für einen schwarzen Screen. Was du brauchst: einen Browser, die kostenlose Arduino IDE und das Morning-Dashboard-Projekt aus Episode 2. Ein Arduino UNO und ein OLED-Modul sind optional; wir führen den Sketch im Simulator aus Episode 1 aus.
Wie das Board mit dem Screen spricht
Vier Drähte: Strom, Takt und Daten
Ein kleines OLED wie unseres braucht vier Drähte. Zwei sind Strom: VCC und GND. Die anderen zwei sind ein Bus namens I2C:
- SCL ist der Takt. Das Board sendet einen stetigen Tick darauf.
- SDA trägt die Daten, ein Bit pro Tick.

Jede Nachricht beginnt mit einer Adresse
Andere Teile können sich dieselben zwei Drähte teilen: Ein Temperatursensor, eine Echtzeituhr und das Display können alle an SCL und SDA hängen. Also beginnt jede Nachricht mit einer Adresse, und nur das Teil mit dieser Adresse antwortet.
Die meisten dieser Displays antworten auf 0x3C. Manche antworten auf 0x3D. Auf vielen Modulen setzt ein winziger Widerstand auf der Rückseite die Adresse, neben einer Beschriftung wie „IIC ADDRESS SELECT 0x78 / 0x7A“. Diese zwei Zahlen sind dieselben Adressen verdoppelt: 0x3C × 2 = 0x78 und 0x3D × 2 = 0x7A. Behalte das für Grund 2 unten im Hinterkopf.

Größere Farbscreens nutzen SPI
Farbscreens wie das TFT aus Episode 4 nutzen stattdessen meist SPI: mehr Drähte (MOSI, SCK, CS, DC und RST), viel schneller, und ein Auswahl-Draht, CS, statt einer Adresse.

Schritt 1: Kopiere den Code aus Lopaka
Öffne das Morning Dashboard aus Episode 2: ein 128×64-OLED mit der Bibliothek U8g2 und zwei Screens, Morning und Night.
Lopaka schreibt die Zeichenfunktionen, eine pro Screen: drawMorning() und drawNight(). Den Sketch um sie herum, mit Display-Einrichtung und loop(), schreibst du einmal in der Arduino IDE.
Klicke im Tab Morning des Code-Panels auf Kopieren, wechsle dann zum Tab Night und kopiere den auch. Kopieren nimmt den Code des offenen Tabs. Der generierte Code ist derselbe wie in Episode 2.

Schritt 2: Installiere U8g2
Öffne in der Arduino IDE den Bibliotheksmanager (das Bücher-Icon links), suche nach U8g2 und klicke bei der U8g2-Bibliothek von oliver auf INSTALLIEREN. Die Episode nutzte Version 2.36.19.
Schritt 3: Wähle das Board
Klicke oben auf Board auswählen, wähle Anderes Board und Port auswählen, tippe uno und wähle Arduino UNO. Ohne angeschlossenes Board kann die IDE den Sketch trotzdem kompilieren; du brauchst den Port nur zum Hochladen.
Schritt 4: Baue den Sketch
Ein neuer Sketch hat bereits setup() und loop(). Füge den Code von Lopaka oben ein und füge dann drei Zeilen hinzu: Binde die Bibliothek ein, erstelle das Display und starte es in setup(). Lösche in loop() den Puffer, zeichne und sende den Puffer an den Screen:
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
// Paste the Lopaka code here: drawMorning() and drawNight()
void setup() {
// put your setup code here, to run once:
u8g2.begin();
}
void loop() {
// put your main code here, to run repeatedly:
u8g2.clearBuffer();
if (millis() / 3000 % 2) drawNight(); else drawMorning();
u8g2.sendBuffer();
}setup() läuft einmal, wenn das Board startet. loop() läuft wieder und wieder. Die if-Zeile zeigt jeden Screen drei Sekunden lang, wie in Episode 2, und die Reihenfolge Löschen, Zeichnen, Senden ist der Frame-Puffer aus Episode 1.

Die Konstruktorzeile beschreibt dein Display
Die lange Zeile unter dem #include ist der Konstruktor. Er beschreibt dein Display, und jeder Teil seines Namens bedeutet etwas:
- SSD1306: der Controller-Chip auf dem Modul.
- 128X64: die Größe in Pixeln.
- NONAME: ein generisches Modul, keine bestimmte Marke.
- F: der Puffer-Modus.
Fist ein voller Frame-Puffer, 1.024 Bytes RAM.1zeichnet den Screen in Pages und braucht nur 128 Bytes. - HW_I2C: die Verdrahtung, Hardware-I2C an den SDA- und SCL-Pins des Boards.
U8G2_R0 bedeutet keine Rotation, und U8X8_PIN_NONE sagt, dass kein Reset-Pin verdrahtet ist. Die U8g2-Bibliothek hat einen Konstruktor für jede Kombination aus Chip, Größe, Puffer und Verdrahtung. Wähle den falschen, und der Screen bleibt schwarz.

Schritt 5: Verifiziere und führe aus
Verifizieren
Klicke oben links auf Verifizieren, das Häkchen. Die IDE kompiliert den Sketch und meldet:
Sketch uses 15394 bytes (47%) of program storage space. Maximum is 32256 bytes.
Global variables use 1600 bytes (78%) of dynamic memory, leaving 448 bytes for local variables. Maximum is 2048 bytes.Der Sketch braucht weniger als die Hälfte des Flash und mehr als drei Viertel des RAM. Der Frame-Puffer allein sind 1.024 der 2.048 Bytes des UNO; alles andere braucht 576. Behalte diese 78 % im Auge: Sie kommen in Grund 5 zurück.

Hochladen oder im Simulator ausführen
Wähle mit angeschlossenem Board seinen Port im selben Dialog Board auswählen und klicke auf Hochladen, den Pfeil neben Verifizieren.
Kein Board? Öffne das Simulatorprojekt aus Episode 1: ein Arduino UNO mit einem SSD1306-Display, verdrahtet GND mit GND, VCC mit 5V, SDA mit A4 und SCL mit A5, und die U8g2-Bibliothek. Füge den Sketch ein und drücke Play. Das Display zeigt den Morning-Screen und wechselt jede drei Sekunden zu Night.

Fünf Gründe, warum ein Screen schwarz bleibt
Die Prüfungen gehen von außen nach innen: Drähte, Adresse, Chip, Code und Speicher. Bei jedem brechen wir die funktionierende Einrichtung im Simulator, sehen den Screen schwarz werden und beheben es.
1. Die Drähte
An einem UNO geht SDA zu A4 und SCL zu A5. Vertausche sie, und das Board spricht mit niemandem: Der Screen bleibt schwarz.
Prüfe auch Strom und Masse. Andere Boards nutzen andere Pins: Auf den meisten ESP32-Boards ist SDA Pin 21 und SCL Pin 22.

2. Die Adresse
Die meisten Module antworten auf 0x3C, manche auf 0x3D. U8g2 spricht mit 0x3C, wenn du ihm nichts anderes sagst. Wenn das Modul auf 0x3D gesetzt ist, antwortet nichts, und der Screen bleibt schwarz.
Um herauszufinden, welches du hast, führe einen I2C-Scanner-Sketch aus. Er fragt jede Adresse auf dem Bus und druckt die, die antworten:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("Scanning I2C...");
for (byte a = 1; a < 127; a++) {
Wire.beginTransmission(a);
if (Wire.endTransmission() == 0) {
Serial.print("Found a device at 0x");
Serial.println(a, HEX);
}
}
Serial.println("Done.");
}
void loop() {}Lade ihn hoch und öffne den Seriellen Monitor mit 9600 Baud.

Setze dann die Adresse in deinem Dashboard-Sketch, vor begin():
void setup() {
u8g2.setI2CAddress(0x3D * 2);
u8g2.begin();
}U8g2 will die Adresse verdoppelt, also wird aus 0x3D 0x3D * 2, 0x7A: dieselbe Zahl, die auf der Rückseite des Moduls gedruckt ist.

3. Der Chip
Zwei Module können genau gleich aussehen und unterschiedliche Controller nutzen. Die meisten kleinen 0,96-Zoll-Screens nutzen den SSD1306. Viele 1,3-Zoll-Modelle nutzen den SH1106. Führe SSD1306-Code auf einem SH1106 aus, und du bekommst einen leeren Screen oder einen Rauschstreifen am Rand.
Die Behebung ist der Chipname im Konstruktor:
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
4. Der Code
U8g2 zeichnet in einen Puffer im Speicher, und nur sendBuffer() bewegt das Bild auf den Screen. Vergiss diese Zeile oder vergiss u8g2.begin() in setup(), und der Screen bleibt dunkel. Der Sketch kompiliert trotzdem ohne Fehler, also prüfe diese Zeilen zuerst:
u8g2.begin(); // in setup()
u8g2.clearBuffer(); // in loop()
drawMorning();
u8g2.sendBuffer();
5. Der Speicher
Erinnerst du dich an diese 78 %? Ein UNO hat 2.048 Bytes RAM, und der Frame-Puffer nimmt die Hälfte.
Lopaka hält Bilder mit PROGMEM im Flash: Der Schalter Als PROGMEM deklarieren neben dem Code ist standardmäßig an, und die Arrays bekommen U8X8_PROGMEM. Schalte ihn aus, und die Bilder wandern ins RAM. Der Mond allein sind 48 × 48 / 8 = 288 Bytes, und die vier Bilder des Dashboards brauchen 416. Jetzt nutzt der Sketch 2.016 Bytes, 98 % des RAM, mit 32 Bytes übrig für alles, was das Programm während des Laufens tut. Er kompiliert trotzdem, aber der Screen fällt auseinander: Im Simulator verschwindet der Text und die Bilder brechen.

Lasse PROGMEM an. Wenn dir trotzdem das RAM ausgeht, wechsle in den Page-Modus: Lege eine 1 statt des F in den Konstruktor, und der Puffer schrumpft von 1.024 Bytes auf 128.
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);Im Page-Modus zeichnet die Bibliothek den Screen in acht Streifen, einer nach dem anderen, also ändert sich auch loop(). Statt clearBuffer() und sendBuffer() geht das Zeichnen in eine firstPage()- / nextPage()-Schleife:
void loop() {
u8g2.firstPage();
do {
if (millis() / 3000 % 2) drawNight(); else drawMorning();
} while (u8g2.nextPage());
}Mit Page-Modus nutzt dasselbe Dashboard 704 Bytes, 34 % des RAM.

Zusammenfassung
- Lopaka zeichnet den Screen, die IDE baut den Sketch darum: Installiere U8g2, wähle das Board, füge die Zeichenfunktionen ein und füge Include, Konstruktor,
begin()und die Löschen-Zeichnen-Senden-Schleife hinzu. - Eine Konstruktorzeile beschreibt dein Display: Chip, Größe, Puffer und Verdrahtung.
- Schwarzer Screen? Prüfe fünf Dinge: die Drähte, die Adresse, den Chip, den Code und den Speicher.
Nächste Episode: Screens & Menüs. Mehr als ein Screen, mit Menüs und einem Button. Lies Episode 6 oder schaue sie auf YouTube.
Bereit, es zu versuchen? Öffne Lopaka und bringe deinen Screen auf ein echtes Board.