Arduino Uno R4 - SSD1309 OLED Display 128x64 | 2.42 Zoll I2C OLED Anleitung

Organic Light-Emitting Diode (OLED) Displays verfügen über selbstleuchtende Pixel, die echte Schwarzwerte, überlegene Kontrastverhältnisse und exzellente Betrachtungswinkel aus allen Richtungen erzeugen — dies bietet erhebliche Vorteile gegenüber herkömmlicher LCD-Technologie. Der SSD1309 Treiber-Chip versorgt die 2.42-Zoll (auch als 2.4-Zoll vermarktet) 128×64 monochromen OLED Module über I2C-Kommunikation.

Arduino Uno R4 SSD1309 OLED 128x64

Diese praktische Anleitung führt Sie durch die Verbindung des SSD1309 OLED 128×64 mit Ihrem Arduino Uno R4 Board über die DIYables_OLED_SSD1309 Bibliothek. Sie werden entdecken, wie Sie:

Benötigte Hardware

1×Arduino Uno R4 WiFi
1×Arduino Uno R4 Minima (Alternativ)
1×USB-Kabel Type-C
1×SSD1309 I2C OLED Display 128x64 (2.42 Zoll)
1×Jumper-Kabel
1×(Empfohlen) Schraubklemmenblock-Shield für Arduino Uno R4
1×(Empfohlen) Sensors/Servo Expansion Shield for Arduino UNO R4
1×(Empfohlen) Breadboard-Shield für Arduino Uno R4
1×(Empfohlen) Gehäuse für Arduino Uno R4
1×(Empfohlen) Stromverteiler für Arduino Uno R4
1×(Empfohlen) Prototyping-Grundplatte & Breadboard-Kit für Arduino Uno

Oder Sie können die folgenden Kits kaufen:

1×DIYables Sensor-Kit (18 Sensoren/Displays)
Offenlegung: Einige der in diesem Abschnitt bereitgestellten Links sind Amazon-Affiliate-Links. Wir können eine Provision für Käufe erhalten, die über diese Links getätigt werden, ohne zusätzliche Kosten für Sie. Wir schätzen Ihre Unterstützung.
Arduino Uno R4 WiFi Compatible Boards

Über das SSD1309 2.42-Zoll OLED Display

Der SSD1309 dient als dedizierter CMOS-Treiber-IC, der für 128×64 Pixel OLED-Matrizen entwickelt wurde. Sein Registersatz behält die Kompatibilität mit dem beliebten SSD1306 bei, wodurch Code-Wiederverwendung mit geringfügigen Anpassungen ermöglicht wird. Bemerkenswerte Hardware-Unterschiede umfassen:

  • Externe Stromversorgung erforderlich — im Gegensatz zur integrierten Ladungspumpe des SSD1306 ist der SSD1309 auf eine externe VCC-Versorgung angewiesen. Jedoch integrieren handelsübliche Breakout-Boards (einschließlich 2.42-Zoll und 2.4-Zoll Varianten) Onboard-Boost-Converter, wodurch dieser Unterschied bei der Verwendung transparent wird.
  • Erweiterte Spannungsbereich — der SSD1309 verarbeitet bis zu 16 V VCC-Eingang, während der SSD1306 bei etwa 4.2 V begrenzt ist.

Das 2.42 Zoll (2.4 Zoll) OLED-Modul verwendet typischerweise den SSD1309-Controller und bietet ein 128×64 Auflösungs-Display, das über das I2C-Protokoll kommuniziert. Die Display-Farbe (weiß, blau, gelb, grün oder dual-farbige Zonen) hängt vom physischen OLED-Substrat ab und kann nicht durch Software-Befehle modifiziert werden.

Diese Anleitung verbindet mit dem Display über den I2C-Bus, erfordert nur zwei Signalleitungen (SDA und SCL) und ermöglicht die Bus-Teilung mit zusätzlichen I2C-Peripheriegeräten.

SSD1309 OLED Pinout (I2C Modul)

Standard 2.42-Zoll SSD1309 I2C OLED Module verfügen über vier Verbindungs-Pins:

  • GND — Verbinden Sie mit Arduino Uno R4 Masse-Referenz.
  • VCC — Stromversorgungseingang. Verbinden Sie mit Arduino Uno R4 5V-Ausgang (oder 3.3V falls das Modul es unterstützt).
  • SCL — I2C-Taktsignalleitung.
  • SDA — I2C-Datensignalleitung.
SSD1309 OLED Pinout

※ Notiz:

  • Die Pin-Anordnung unterscheidet sich zwischen Herstellern. Überprüfen Sie immer die Siebdruck-Beschriftungen auf Ihrem spezifischen Modul, bevor Sie Verbindungen herstellen.
  • Diese Anleitung wurde mit dem 2.42 Zoll SSD1309 OLED Display von DIYables validiert. Andere SSD1309-basierte 2.4/2.42-Zoll Module sollten identisch funktionieren.

Verdrahtungsschema — Arduino Uno R4 & SSD1309 OLED 128×64

  • Schematische Verbindungen zwischen Arduino Uno R4 und dem 2.42 Zoll SSD1309 OLED 128×64
Arduino Uno R4 SSD1309 OLED 128x64 wiring diagram

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.

Soll die Verkabelung fest an ihrem Platz bleiben? Stecken Sie einfach ein Proto Screw Terminal Block Shield oder ein Screw Shield V2 auf den Arduino UNO R4. Das Diagramm unten zeigt dieselbe Verdrahtung mit dem Screw Shield V2.

Arduino Uno R4 SSD1309 OLED 128x64 wiring diagram (Screw Shield V2)

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.

  • Physische Verdrahtungs-Fotografie zwischen Arduino Uno R4 und SSD1309 OLED 128×64
Arduino Uno R4 SSD1309 OLED 128x64 real wiring

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.

Siehe Der beste Weg, den Arduino Uno R4 und andere Komponenten mit Strom zu versorgen.

Der Arduino Uno R4 verwendet dieselben I2C-Pin-Positionen wie der klassische Uno. Verbindungsdetails:

OLED ModulArduino Uno R4
Vin5V
GNDGND
SDAA4 (oder SDA Pin)
SCLA5 (oder SCL Pin)

Erste Schritte — SSD1309 OLED mit Arduino Uno R4

Schritt 1: Installation der DIYables_OLED_SSD1309 Bibliothek

  • Starten Sie die Arduino IDE und klicken Sie auf das Libraries Symbol in der linken Seitenleiste.
  • Geben Sie "DIYables_OLED_SSD1309" in das Suchfeld ein und finden Sie die Bibliothek von DIYables.
  • Klicken Sie auf die Install Schaltfläche.
Arduino SSD1309 OLED library
  • Die IDE wird Sie auffordern, die erforderliche Abhängigkeit (Adafruit GFX Library) zu installieren. Klicken Sie auf Install All.
Arduino Adafruit GFX library

Schritt 2: Grundlegende Programmstruktur

Alle SSD1309-Sketches folgen dieser konsistenten Struktur: Header einbinden, ein Display-Objekt instanziieren, es in setup() initialisieren, Inhalt in den Frame-Buffer zeichnen, dann den Buffer mit display() auf den Bildschirm übertragen.

  • Notwendige Header einbinden:
#include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h>
  • Die Bildschirmdimensionen definieren (128×64 für das 2.42-Zoll Modul):
#define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  • Das Display-Objekt instanziieren (verwenden Sie -1 wenn kein Reset-Pin verbunden ist):
// Create an SSD1309 display instance on the default I2C bus DIYables_OLED_SSD1309 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
  • Das Display innerhalb von setup() initialisieren:
// Initialize the SSD1309 — use address 0x3C (default for most modules) if (!oled.begin(SSD1309_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1309 allocation failed")); while (true); }
  • Nach der Initialisierung rufen Sie Zeichenfunktionen (clearDisplay(), drawPixel(), print(), etc.) gefolgt von oled.display() auf, um den Bildschirm zu aktualisieren.

※ Notiz:

Alle Code-Beispiele in dieser Anleitung zielen auf das SSD1309 OLED 128×64 (2.42 Zoll) ab und verwenden die DIYables_OLED_SSD1309 Bibliothek mit Arduino Uno R4.

Arduino Uno R4 Code — Hello World auf SSD1309 OLED

Die einfachste Demonstration: Text in verschiedenen Größen anzeigen.

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Hello World * Prints text in two sizes on the 2.42 inch 128x64 I2C OLED. * Compatible with Arduino Uno R4 WiFi and Arduino Uno R4 Minima. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.setTextSize(1); // 6x8 pixels per character display.setTextColor(SSD1309_PIXEL_ON); // turn pixels on display.setCursor(0, 0); display.println(F("Hello, World!")); display.println(); display.setTextSize(2); // 12x16 pixels per character display.println(F("DIYables")); display.setTextSize(1); display.println(); display.println(F("SSD1309 OLED 128x64")); display.display(); // push buffer to screen } void loop() { }

Arduino Uno R4 Code — Text auf SSD1309 OLED anzeigen

Dieses Beispiel zeigt erweiterte Textfunktionen — variable Größen, numerische Formatierung und das F() Makro zur RAM-Einsparung.

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Display Text Demo for Arduino Uno R4 * Demonstrates text display features on 2.42" SSD1309 128x64 I2C OLED. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } delay(2000); // wait for initializing display.clearDisplay(); // clear display display.setTextSize(1); // text size = 1 display.setTextColor(SSD1309_PIXEL_ON); // set text color display.setCursor(0, 10); // set position to display display.println(F("Text size = 1")); // display text display.display(); // update display delay(2000); display.setTextSize(2); // text size = 2 display.setCursor(0, 30); // set position to display display.println(F("Size = 2")); // display text display.display(); // update display delay(2000); display.clearDisplay(); // clear display display.setTextSize(1); display.setCursor(0, 0); display.println(F("Display integer:")); display.println(12345); display.println(); display.println(F("Display float:")); display.println(1.2345); display.println(); display.println(F("Display HEX:")); display.println(0xABCD, HEX); display.display(); // update display } void loop() { }

Nützliche Display-Funktionen Referenz

Schnellreferenz für häufig verwendete SSD1309 OLED-Funktionen über die DIYables-Bibliothek:

  • oled.clearDisplay() — Frame-Buffer löschen (alle Pixel aus).
  • oled.display() — Buffer zum OLED übertragen, um Änderungen sichtbar zu machen.
  • oled.drawPixel(x, y, color) — einzelnes Pixel setzen oder löschen.
  • oled.setTextSize(n) — Schriftart um Faktor *n* skalieren (1 = 6×8, 2 = 12×16, …, bis zu 8).
  • oled.setCursor(x, y) — Text-Cursor auf Pixelkoordinaten *(x, y)* positionieren.
  • oled.setTextColor(SSD1309_PIXEL_ON) — nur Text-Vordergrund (transparenter Hintergrund).
  • oled.setTextColor(SSD1309_PIXEL_OFF, SSD1309_PIXEL_ON) — Text mit expliziter Hintergrundfarbe.
  • oled.println("message") — String drucken und zur nächsten Zeile wechseln.
  • oled.println(number) — Integer im Dezimalformat drucken.
  • oled.println(number, HEX) — Integer im Hexadezimalformat drucken.
  • oled.startscrollright(start, stop) — Hardware-Scrolling nach rechts zwischen Seite *start* und Seite *stop*.
  • oled.startscrollleft(start, stop) — Hardware-Scrolling nach links.
  • oled.startscrolldiagright(start, stop) — Hardware-Scrolling diagonal nach rechts.
  • oled.startscrolldiagleft(start, stop) — Hardware-Scrolling diagonal nach links.
  • oled.stopscroll() — jedes aktive Hardware-Scrolling stoppen.
  • oled.setContrast(value) — Display-Helligkeit anpassen (0–255).
  • oled.dim(true/false) — Display schnell auf Minimum dimmen oder vorherigen Kontrast wiederherstellen.
  • oled.invertDisplay(true/false) — Hardware-Farbinversion (Ein-Pixel ↔ Aus-Pixel).

Wie man Text vertikal und horizontal auf dem SSD1309 OLED zentriert

Siehe How to vertical/horizontal center on OLED

Arduino Uno R4 Code — Formen auf SSD1309 OLED zeichnen

Die DIYables_OLED_SSD1309 Bibliothek erbt von Adafruit_GFX und bietet vollständige Formen-Zeichnungsfunktionen: Pixel, Linien, Rechtecke, gefüllte Rechtecke, Kreise, gefüllte Kreise, Dreiecke, gefüllte Dreiecke und abgerundete Rechtecke. Der folgende Sketch demonstriert alle mit animierten Sequenzen.

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Draw Shapes for Arduino Uno R4 * Cycles through every shape primitive on the 2.42" SSD1309 128x64 OLED. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); } void loop() { // --- Pixels --- display.clearDisplay(); for (int16_t i = 0; i < display.width(); i += 4) { display.drawPixel(i, i * display.height() / display.width(), SSD1309_PIXEL_ON); } display.display(); delay(1500); // --- Lines --- display.clearDisplay(); for (int16_t i = 0; i < display.width(); i += 8) { display.drawLine(0, 0, i, display.height() - 1, SSD1309_PIXEL_ON); } for (int16_t i = 0; i < display.height(); i += 8) { display.drawLine(0, 0, display.width() - 1, i, SSD1309_PIXEL_ON); } display.display(); delay(1500); // --- Rectangles --- display.clearDisplay(); for (int16_t i = 0; i < display.height() / 2; i += 4) { display.drawRect(i, i, display.width() - 2 * i, display.height() - 2 * i, SSD1309_PIXEL_ON); } display.display(); delay(1500); // --- Filled rectangles (inverse) --- display.clearDisplay(); for (int16_t i = 0; i < display.height() / 2; i += 6) { display.fillRect(i, i, display.width() - 2 * i, display.height() - 2 * i, SSD1309_PIXEL_INVERSE); } display.display(); delay(1500); // --- Circles --- display.clearDisplay(); for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 5) { display.drawCircle(display.width() / 2, display.height() / 2, i, SSD1309_PIXEL_ON); } display.display(); delay(1500); // --- Filled circles (inverse) --- display.clearDisplay(); for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 6) { display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1309_PIXEL_INVERSE); } display.display(); delay(1500); // --- Rounded rectangles --- display.clearDisplay(); for (int16_t i = 0; i < display.height() / 2 - 2; i += 4) { display.drawRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i, display.height() / 4, SSD1309_PIXEL_ON); } display.display(); delay(1500); // --- Filled rounded rectangles (inverse) --- display.clearDisplay(); for (int16_t i = 0; i < display.height() / 2 - 2; i += 4) { display.fillRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i, display.height() / 4, SSD1309_PIXEL_INVERSE); } display.display(); delay(1500); // --- Triangles --- display.clearDisplay(); for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 5) { display.drawTriangle( display.width() / 2, display.height() / 2 - i, display.width() / 2 - i, display.height() / 2 + i, display.width() / 2 + i, display.height() / 2 + i, SSD1309_PIXEL_ON); } display.display(); delay(1500); // --- Filled triangles (inverse) --- display.clearDisplay(); for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 6) { display.fillTriangle( display.width() / 2, display.height() / 2 - i, display.width() / 2 - i, display.height() / 2 + i, display.width() / 2 + i, display.height() / 2 + i, SSD1309_PIXEL_INVERSE); } display.display(); delay(1500); }

Arduino Uno R4 Code — Hardware-Scrolling auf SSD1309 OLED

Der SSD1309 umfasst eine Hardware-Scrolling-Engine, die Display-Inhalte ohne CPU-Intervention bewegt. Die DIYables-Bibliothek bietet vier Scroll-Modi: rechts, links, diagonal-rechts und diagonal-links. Jeder akzeptiert einen Start-Seiten- und Stop-Seiten-Parameter (Seiten sind 8-Pixel-hohe horizontale Bänder, nummeriert 0–7 auf einem 64-Pixel-hohen Display).

※ Notiz:

Rufen Sie immer display() auf, um Ihren Inhalt zum OLED zu übertragen bevor Sie ein Scrolling initiieren. Vermeiden Sie das Rendern neuer Inhalte während das Scrolling aktiv ist — rufen Sie zuerst stopscroll() auf.

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Scroll Text * Demonstrates all four hardware scroll directions on the 2.42" OLED. * Compatible with Arduino Uno R4 WiFi and Arduino Uno R4 Minima. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(10, 24); display.println(F("DIYables")); display.display(); delay(2000); } void loop() { // Scroll right across all pages display.startscrollright(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); // Scroll left display.startscrollleft(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); // Diagonal scroll right display.startscrolldiagright(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); // Diagonal scroll left display.startscrolldiagleft(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); }

Arduino Uno R4 Code — Bitmap-Bild auf SSD1309 OLED anzeigen

Um eine Bitmap auf dem SSD1309 OLED anzuzeigen, müssen Sie zuerst Ihr Bild in ein C-Byte-Array konvertieren. Verwenden Sie das kostenlose image2cpp Online-Tool für diese Konvertierung:

  1. Laden Sie Ihre Bilddatei hoch (PNG, JPG, BMP, etc.).
  2. Konfigurieren Sie die Canvas-Größe auf 128×64 (oder kleiner).
  3. Wählen Sie Arduino code als Ausgabeformat.
  4. Kopieren Sie das generierte Array in Ihren Sketch.
image to bitmap array

Das folgende Beispiel wechselt zwischen einem 16×16 Herz-Icon und einem vollbreiten DIYables-Logo:

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Display Image Demo for Arduino Uno R4 * Displays bitmap images on the 2.42" SSD1309 128x64 I2C OLED. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // 16x16 heart bitmap const unsigned char heart16x16[] PROGMEM = { 0x00, 0x00, 0x03, 0xc0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x03, 0xc0, 0x00, 0x00 }; // 128x64 DIYables logo bitmap const unsigned char diyablesLogo[] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xf0, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0x80, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x7f, 0xff, 0x00, 0x0f, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x7f, 0xff, 0x80, 0x0f, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x7f, 0xff, 0x80, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x7f, 0xff, 0x80, 0x07, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x7f, 0xff, 0x80, 0x07, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x07, 0x80, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xe0, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xe0, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xfc, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } delay(2000); display.setCursor(0, 0); } void loop() { // Display 16x16 heart icon display.clearDisplay(); display.drawBitmap((SCREEN_WIDTH - 16) / 2, (SCREEN_HEIGHT - 16) / 2, heart16x16, 16, 16, SSD1309_PIXEL_ON); display.display(); delay(2000); // Display full-screen DIYables logo display.clearDisplay(); display.drawBitmap(0, 0, diyablesLogo, 128, 64, SSD1309_PIXEL_ON); display.display(); delay(2000); // Invert display display.invertDisplay(true); delay(2000); display.invertDisplay(false); delay(500); }

※ Notiz:

  • Bitmap-Dimensionen dürfen die Bildschirmauflösung nicht überschreiten (128×64 für das 2.42 Zoll Modul).

Arduino Uno R4 Code — Kontrast und Dimmen auf SSD1309 OLED

Der SSD1309 bietet 256 Kontraststufen (0–255). Die DIYables-Bibliothek stellt setContrast() für präzise Kontrolle und dim() für schnelles Umschalten zwischen minimaler Helligkeit und dem zuvor eingestellten Level bereit.

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Contrast & Dim * Sweeps contrast from 0→255→0 then toggles dim mode on the 2.42" OLED. * Compatible with Arduino Uno R4 WiFi and Arduino Uno R4 Minima. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } // Draw a test pattern so the contrast changes are visible display.clearDisplay(); display.fillRect(0, 0, 64, 32, SSD1309_PIXEL_ON); display.fillRect(64, 32, 64, 32, SSD1309_PIXEL_ON); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_INVERSE); display.setCursor(16, 28); display.println(F("Contrast Demo")); display.display(); delay(2000); } void loop() { // Ramp up for (int c = 0; c <= 255; c += 5) { display.setContrast((uint8_t)c); delay(30); } delay(1000); // Ramp down for (int c = 255; c >= 0; c -= 5) { display.setContrast((uint8_t)c); delay(30); } delay(1000); // Quick dim toggle display.dim(true); // minimum brightness delay(2000); display.dim(false); // restore delay(2000); }

Arduino Uno R4 Code — Benutzerdefinierte externe Schriftarten auf SSD1309 OLED

Die Adafruit GFX Bibliothek umfasst Dutzende skalierbarer FreeFont Schriftarten (Serif, Sans, Mono — jeweils in Regular, Bold, Italic und mehreren Größen). Sie können jede davon auf dem SSD1309 Display verwenden, indem Sie den relevanten Header einbinden und setFont() aufrufen.

※ Notiz:

  • Wenn eine externe Schriftart aktiv ist, bezieht sich die Cursor-Y-Koordinate auf die Text-Grundlinie, nicht auf die obere linke Ecke. Dies unterscheidet sich vom Verhalten der eingebauten 5×7 Schriftart.
  • Externe Schriftarten werden im Flash (PROGMEM) gespeichert. Bei speicherbeschränkten Boards wie dem klassischen Uno (32 KB Flash) verwenden Sie sie sparsam. Der Arduino Uno R4 hat mehr Speicher und ermöglicht mehr Flexibilität.
/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – External Fonts * Cycles through three FreeFont typefaces on the 2.42" SSD1309 OLED. * Compatible with Arduino Uno R4 WiFi and Arduino Uno R4 Minima. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #include <Fonts/FreeSerif9pt7b.h> #include <Fonts/FreeSansBold12pt7b.h> #include <Fonts/FreeMono9pt7b.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.display(); } void loop() { // ── Built-in 5×7 font ── display.clearDisplay(); display.setFont(NULL); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 0); display.println(F("Built-in 5x7 font")); display.println(); display.setTextSize(2); display.println(F("DIYables")); display.display(); delay(3000); // ── FreeSerif 9pt ── display.clearDisplay(); display.setFont(&FreeSerif9pt7b); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 14); // Y = baseline display.println(F("FreeSerif 9pt")); display.setCursor(0, 38); display.println(F("DIYables OLED")); display.setCursor(0, 58); display.println(F("Hello World!")); display.display(); delay(3000); // ── FreeSansBold 12pt ── display.clearDisplay(); display.setFont(&FreeSansBold12pt7b); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 20); display.println(F("SansBold")); display.setCursor(0, 52); display.println(F("DIYables")); display.display(); delay(3000); // ── FreeMono 9pt ── display.clearDisplay(); display.setFont(&FreeMono9pt7b); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 14); display.println(F("FreeMono 9pt")); display.setCursor(0, 34); display.println(F("0123456789")); display.setCursor(0, 54); display.println(F("!@#$%^&*()")); display.display(); delay(3000); }

Video Tutorial

Wir erwägen die Erstellung von Video-Tutorials. Wenn Sie Video-Tutorials für wichtig halten, abonnieren Sie bitte unseren YouTube-Kanal , um uns zu motivieren, die Videos zu erstellen.

Die folgende Video-Demo verwendet den folgenden Code:

/* * Dieser Arduino UNO R4 Code wurde von newbiely.de entwickelt * Dieser Arduino UNO R4 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/arduino-uno-r4/arduino-uno-r4-ssd1309-oled-display */ /* * Robot Eyes v4 - Arduino UNO R4 + OLED SSD1309 2.42" (I2C) + TTP223 * Libraries: DIYables_OLED_SSD1309 and Adafruit GFX * * Design: white elliptical sclera + black pupils with highlights + angled eyelids. * All eye elements are drawn in code for smooth animation. * * Wiring: * OLED VCC -> 5V, GND -> GND, SDA -> A4/SDA, SCL -> A5/SCL * TTP223 VCC -> 5V (or 3.3V), GND -> GND, I/O -> D13 * * Behavior: * - Each tap triggers a quick blink and switches to the next expression: * NORMAL -> HAPPY -> WINK -> ANGRY -> SAD -> CRY -> STAR -> DIZZY * -> LOVE -> SURPRISED -> SUSPICIOUS -> ROLL -> SLEEPY -> (back to NORMAL) * - After RETURN_NORMAL_MS (10s) of inactivity, return to NORMAL. * - After SLEEP_MS (30s) of inactivity, enter SLEEP mode. * - Tap while sleeping to wake up and return to NORMAL. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C #define TOUCH_PIN 13 #define ON SSD1309_PIXEL_ON #define OFF SSD1309_PIXEL_OFF // Adjustable parameters const int EYE_RX = 22; // horizontal eye radius const int EYE_RY = 25; // vertical eye radius const int EYE_CY = 32; // eye center on the Y axis const int CX_L = 32; // left eye center const int CX_R = 96; // right eye center const unsigned long RETURN_NORMAL_MS = 10000; const unsigned long SLEEP_MS = 30000; //must be greater than RETURN_NORMAL_MS const unsigned long DEBOUNCE_MS = 60; const unsigned long TRANSITION_MS = 110; //transition blink duration const unsigned long FRAME_MS = 33; // ~30 FPS DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); enum Mood { NORMAL, HAPPY, WINK, ANGRY, SAD, CRY, STAR, DIZZY, LOVE, SURPRISED, SUSPICIOUS, ROLL, SLEEPY, SLEEP }; const Mood ORDER[] = { NORMAL, HAPPY, WINK, ANGRY, SAD, CRY, STAR, DIZZY, LOVE, SURPRISED, SUSPICIOUS, ROLL, SLEEPY }; const uint8_t ORDER_N = sizeof(ORDER) / sizeof(ORDER[0]); Mood mood = NORMAL; uint8_t moodIndex = 0; unsigned long moodStart = 0, transUntil = 0; // Look direction (-1..1) float curX = 0, curY = 0, tgtX = 0, tgtY = 0; unsigned long nextLook = 0; // Blinking bool blinking = false; unsigned long blinkStart = 0, nextBlink = 0; const unsigned long BLINK_MS = 170; // Touch sensor bool lastReading = false, stableState = false; unsigned long lastChange = 0, lastActivity = 0, lastFrame = 0; // Eye model struct Style { // expression parameters float lx, ly; // look direction -1..1 float pr; // pupil radius (0 = do not draw) float topIn, topOut; // upper eyelid coverage in pixels (inner / outer) float bot; // lower eyelid coverage in pixels int rx, ry, cy; // eye size and position int shake; // horizontal shake (px) }; struct Eye { // calculated geometry for each eye int cx, cy, rx, ry; float topIn, topOut, bot; int inner; // +1: left eye (inner side is right), -1: right eye }; Style baseStyle() { Style s = { 0, 0, 13, 0, 0, 0, EYE_RX, EYE_RY, EYE_CY, 0 }; return s; } Eye makeEye(int side, const Style& s) { Eye e; e.cx = (side == 0 ? CX_L : CX_R) + s.shake + (int)(s.lx * 3); // slightly offset eye toward look direction e.cy = s.cy + (int)(s.ly * 2); e.rx = s.rx; e.ry = s.ry; e.topIn = s.topIn; e.topOut = s.topOut; e.bot = s.bot; e.inner = (side == 0) ? 1 : -1; return e; } float lidTopAt(const Eye& e, float u) { // u: -1..1 across the eye width float t = (e.inner * u + 1.0) * 0.5; // 0 = outer side, 1 = inner side return e.cy - e.ry + e.topOut + (e.topIn - e.topOut) * t; } // Draw the eyeball column by column, clipped by the eyelids. void drawEyeball(const Eye& e) { for (int dx = -e.rx; dx <= e.rx; dx++) { float u = (float)dx / e.rx; float hy = e.ry * sqrt(1.0 - u * u); float y0 = e.cy - hy, y1 = e.cy + hy; float lt = lidTopAt(e, u); float lb = e.cy + e.ry - e.bot; if (y0 < lt) y0 = lt; if (y1 > lb) y1 = lb; if (y1 >= y0) display.drawFastVLine(e.cx + dx, (int)y0, (int)(y1 - y0) + 1, ON); } } // Draw the pupil and highlights. Highlights are skipped when covered by the eyelids. void drawPupil(const Eye& e, const Style& s) { int pr = (int)(s.pr + 0.5); float mx = e.rx - pr - 2; if (mx < 0) mx = 0; float my = e.ry - pr - 2; if (my < 0) my = 0; int px = e.cx + (int)(s.lx * mx); int py = e.cy + (int)(s.ly * my); display.fillCircle(px, py, pr, OFF); float lb = e.cy + e.ry - e.bot; int hr = max(2, pr / 4); int hx = px - pr / 3, hy = py - pr / 3; if (hy - hr > lidTopAt(e, (float)(hx - e.cx) / e.rx) + 1 && hy + hr < lb - 1) display.fillCircle(hx, hy, hr, ON); int h2x = px + pr / 3, h2y = py + pr / 3; if (pr >= 8 && h2y + 1 < lb - 1) display.fillCircle(h2x, h2y, 1, ON); } void drawEyeSide(int side, const Style& s) { Eye e = makeEye(side, s); drawEyeball(e); if (s.pr > 0) drawPupil(e, s); } void drawPair(const Style& s) { drawEyeSide(0, s); drawEyeSide(1, s); } // Auxiliary shapes drawn inside the eyeball void drawHeart(int cx, int cy, int r, uint16_t col) { display.fillCircle(cx - r, cy - r / 2, r, col); display.fillCircle(cx + r, cy - r / 2, r, col); display.fillTriangle(cx - 2 * r + 1, cy - r / 2 + 2, cx + 2 * r - 1, cy - r / 2 + 2, cx, cy + 2 * r + 2, col); } void drawStar(int cx, int cy, float R, float rot, uint16_t col) { float px[10], py[10]; for (int i = 0; i < 10; i++) { float ang = rot + i * PI / 5.0 - PI / 2.0; float rad = (i % 2 == 0) ? R : R * 0.45; px[i] = cx + cos(ang) * rad; py[i] = cy + sin(ang) * rad; } for (int i = 0; i < 10; i++) { int j = (i + 1) % 10; display.fillTriangle(cx, cy, (int)px[i], (int)py[i], (int)px[j], (int)py[j], col); } } void drawSpiral(int cx, int cy, float phase, int dir, uint16_t col) { float px = cx, py = cy; for (float a = 0.4; a <= 11.5; a += 0.4) { float rad = a * 1.3; float ang = dir * (a + phase); float x = cx + cos(ang) * rad, y = cy + sin(ang) * rad; display.drawLine((int)px, (int)py, (int)x, (int)y, col); display.drawLine((int)px + 1, (int)py, (int)x + 1, (int)y, col); px = x; py = y; } } void drawHappyEye(int cx, int cy) { // smiling arch eye "^" display.fillCircle(cx, cy + 10, 17, ON); display.fillCircle(cx, cy + 18, 17, OFF); } void drawClosedEye(int cx, int cy) { // Closed eye display.fillRoundRect(cx - EYE_RX, cy - 1, 2 * EYE_RX, 3, 1, ON); } // Expressions void drawNormal(unsigned long now) { float cover = 0; if (blinking) { float p = (float)(now - blinkStart) / BLINK_MS; if (p >= 1.0) { blinking = false; nextBlink = now + (random(5) == 0 ? 180 : random(2000, 5500)); // occasional double blink } else { cover = sin(p * PI) * EYE_RY * 0.96; } } else if (now >= nextBlink) { blinking = true; blinkStart = now; } Style s = baseStyle(); s.lx = curX; s.ly = curY; s.pr = 13 + sin(now / 700.0) * 0.7; // subtle pupil breathing animation s.topIn = s.topOut = s.bot = cover; drawPair(s); } void drawHappy(unsigned long now) { int bob = (int)(sin(now / 120.0) * 3); drawHappyEye(CX_L, EYE_CY - 4 + bob); drawHappyEye(CX_R, EYE_CY - 4 + bob); } void drawWink(unsigned long now) { Style s = baseStyle(); s.pr = 13 + sin(now / 700.0) * 0.7; drawEyeSide(0, s); drawHappyEye(CX_R, EYE_CY - 4); } void drawAngry() { Style s = baseStyle(); s.pr = 10; s.ly = 0.15; s.topIn = 26; s.topOut = 1; s.bot = 3; s.shake = random(-1, 2); drawPair(s); } void drawSad() { Style s = baseStyle(); s.ly = 0.6; s.topIn = 0; s.topOut = 18; drawPair(s); } void drawCry(unsigned long now) { Style s = baseStyle(); s.rx = 20; s.ry = 22; s.cy = 26; s.pr = 12; s.ly = 0.6; s.topIn = 0; s.topOut = 16; drawPair(s); int tx[2] = { CX_L - 8, CX_R + 8 }; for (int i = 0; i < 2; i++) { int ty = 44 + (int)((now / 55 + i * 9) % 19); display.fillCircle(tx[i], ty, 2, ON); display.fillTriangle(tx[i] - 2, ty, tx[i] + 2, ty, tx[i], ty - 5, ON); } } void drawStarEyes(unsigned long now) { float R = 15 + sin(now / 150.0) * 1.5; float rot = sin(now / 500.0) * 0.25; Style s = baseStyle(); for (int side = 0; side < 2; side++) { Eye e = makeEye(side, s); drawEyeball(e); drawStar(e.cx, e.cy, R, rot, OFF); } } void drawDizzy(unsigned long now) { float phase = now / 120.0; Style s = baseStyle(); for (int side = 0; side < 2; side++) { Eye e = makeEye(side, s); drawEyeball(e); drawSpiral(e.cx, e.cy, phase, side == 0 ? 1 : -1, OFF); } } void drawLove(unsigned long now) { int r = 7 + (int)(sin(now / 150.0) * 1.5); Style s = baseStyle(); for (int side = 0; side < 2; side++) { Eye e = makeEye(side, s); drawEyeball(e); drawHeart(e.cx, e.cy - 3, r, OFF); } } void drawSurprised() { Style s = baseStyle(); s.rx = 24; s.ry = 28; s.pr = 5; drawPair(s); } void drawSuspicious(unsigned long now) { Style s = baseStyle(); s.pr = 11; s.lx = sin(now / 700.0); s.ly = 0.1; s.topIn = s.topOut = 22; s.bot = 8; drawPair(s); } void drawRoll(unsigned long now) { float t = (float)((now - moodStart) % 1300) / 1300.0 * 2.0 * PI; Style s = baseStyle(); s.lx = cos(t); s.ly = sin(t) * 0.9; drawPair(s); } void drawSleepy(unsigned long now) { float k = (sin(now / 450.0) + 1.0) / 2.0; // drowsy motion Style s = baseStyle(); s.lx = curX * 0.3; s.ly = 0.5; s.topIn = s.topOut = 10 + k * 24; s.bot = 3; drawPair(s); } void drawSleep(unsigned long now) { int cx[2] = { CX_L, CX_R }; for (int i = 0; i < 2; i++) { // Closed eye cong "︶" display.fillCircle(cx[i], EYE_CY - 2, 18, ON); display.fillCircle(cx[i], EYE_CY - 5, 18, OFF); } int phase = (now / 600) % 3; display.setTextColor(ON); display.setTextSize(1 + phase); display.setCursor(104 - phase * 6, 12 - phase * 4); display.print(phase == 0 ? F("z") : F("Z")); } void updateLook(unsigned long now) { if (now >= nextLook) { if (random(4) == 0) { tgtX = 0; tgtY = 0; } else { tgtX = random(-100, 101) / 100.0; tgtY = random(-70, 71) / 100.0; } nextLook = now + random(1200, 3500); } curX += (tgtX - curX) * 0.3; curY += (tgtY - curY) * 0.3; } void setMood(Mood m) { unsigned long now = millis(); if (mood == SLEEP && m != SLEEP) display.dim(false); if (m == SLEEP && mood != SLEEP) display.dim(true); if (m == NORMAL) { blinking = false; nextBlink = now + random(1500, 4000); } mood = m; moodStart = now; } bool touchPressed(unsigned long now) { bool reading = (digitalRead(TOUCH_PIN) == HIGH); if (reading != lastReading) { lastChange = now; lastReading = reading; } if ((now - lastChange) >= DEBOUNCE_MS && reading != stableState) { stableState = reading; if (stableState) return true; } return false; } void onTap(unsigned long now) { lastActivity = now; transUntil = now + TRANSITION_MS; // quick blink during expression transition if (mood == SLEEP) { moodIndex = 0; setMood(NORMAL); return; } moodIndex = (moodIndex + 1) % ORDER_N; setMood(ORDER[moodIndex]); } void setup() { Serial.begin(9600); pinMode(TOUCH_PIN, INPUT); randomSeed(analogRead(A0)); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } Wire.setClock(400000); display.clearDisplay(); display.display(); unsigned long now = millis(); lastActivity = now; nextBlink = now + 2500; nextLook = now + 1500; } void loop() { unsigned long now = millis(); if (touchPressed(now)) onTap(now); if (stableState) lastActivity = now; unsigned long idle = now - lastActivity; if (mood != SLEEP) { if (idle >= SLEEP_MS) { moodIndex = 0; setMood(SLEEP); } else if (idle >= RETURN_NORMAL_MS && mood != NORMAL) { moodIndex = 0; setMood(NORMAL); } } if (now - lastFrame < FRAME_MS) return; lastFrame = now; if (mood == NORMAL || mood == SLEEPY) updateLook(now); display.clearDisplay(); if (now < transUntil) { drawClosedEye(CX_L, EYE_CY); drawClosedEye(CX_R, EYE_CY); } else { switch (mood) { case NORMAL: drawNormal(now); break; case HAPPY: drawHappy(now); break; case WINK: drawWink(now); break; case ANGRY: drawAngry(); break; case SAD: drawSad(); break; case CRY: drawCry(now); break; case STAR: drawStarEyes(now); break; case DIZZY: drawDizzy(now); break; case LOVE: drawLove(now); break; case SURPRISED: drawSurprised(); break; case SUSPICIOUS: drawSuspicious(now); break; case ROLL: drawRoll(now); break; case SLEEPY: drawSleepy(now); break; case SLEEP: drawSleep(now); break; } } display.display(); }

SSD1309 OLED Fehlerbehebung mit Arduino Uno R4

Wenn das 2.42 Zoll SSD1309 OLED nach dem Hochladen Ihres Sketches leer bleibt, arbeiten Sie diese Diagnoseschritte durch:

  • Verbindungen überprüfen — bestätigen Sie, dass SDA, SCL, VCC und GND mit den korrekten Arduino Uno R4 Pins verdrahtet sind.
  • Treiber-Chip bestätigen — diese Bibliothek ist für den SSD1309 entwickelt. Wenn Ihr Modul einen anderen Controller verwendet (z.B. SH1106), wird es nicht korrekt antworten.
  • I2C-Adresse prüfen — die meisten SSD1309 Module verwenden standardmäßig 0x3C, aber einige verwenden 0x3D. Führen Sie den I2C-Scanner-Sketch unten aus, um die tatsächliche Adresse zu erkennen:
// I2C address scanner — prints every detected device to the Serial Monitor #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices = 0; Serial.println("Scanning..."); for (address = 1; address < 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknown error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devices found"); else Serial.println("done"); delay(5000); }

Erwartete Serial Monitor Ausgabe, wenn der SSD1309 erkannt wird:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' on 'COM15')
New Line
9600 baud
Scanning... I2C device found at address 0x3C ! done
Ln 11, Col 1
Arduino Uno R4 WiFi on COM15
2
  • Sicherstellen, dass display() aufgerufen wird — der SSD1309 verwendet einen Frame-Buffer. Zeichenfunktionen modifizieren nur den Buffer im RAM; nichts erscheint auf dem Bildschirm, bis Sie oled.display() aufrufen.
  • Stromversorgung prüfen — das 2.42 Zoll Modul zieht mehr Strom als kleinere OLEDs. Stellen Sie sicher, dass Ihre Stromquelle ausreichend Strom liefern kann (typischerweise 20–40 mA bei voller Helligkeit).

※ UNSERE NACHRICHTEN

  • Sie können gerne den Link zu diesem Tutorial teilen. Bitte verwenden Sie jedoch unsere Inhalte nicht auf anderen Websites. Wir haben viel Mühe und Zeit in die Erstellung der Inhalte investiert, bitte respektieren Sie unsere Arbeit!