Pantallas OLED con Arduino: tecnología y conexión

FunduinoÚltima actualización el

Drei Größen, zwei Bussysteme und die Bibliothek u8g2

OLED-Displays leuchten selbst und brauchen deshalb keine Hintergrundbeleuchtung. Das macht sie klein, kontrastreich und sparsam – und zu einer beliebten Anzeige für Arduino-Projekte.

Diese Seite erklärt, wie ein OLED technisch funktioniert, worin sich die gängigen Größen unterscheiden, wie du sie über I²C oder SPI anschließt – und zeigt an einem ausführlichen Beispiel, was die Bibliothek u8g2 alles zeichnen kann.

Schaltplan mit 2,42-Zoll-OLED über SPI am Arduino UNO
Schaltplan: 2,42-Zoll-OLED mit SSD1309 am Arduino

Wie ein OLED funktioniert

OLED steht für Organic Light Emitting Diode. Anders als LCDs (Liquid Crystal Display, also Flüssigkristallanzeige) brauchen OLEDs keine Hintergrundbeleuchtung – sie leuchten selbst.

Ein OLED besteht aus zwei Elektroden, von denen mindestens eine durchsichtig sein muss. Dazwischen liegen organische Halbleiterschichten aus natürlichen Farbstoffen. Diese Schichten leuchten, sobald Gleichstrom durch sie fließt. Grundlage dafür ist die Elektrolumineszenz: Ein Festkörper wird durch das Anlegen einer elektrischen Spannung dazu angeregt, Licht zu erzeugen.

Die verschiedenen OLEDs unterscheiden sich in der Größe und darin, wie der Mikrocontroller sie anspricht. Der Datenbus I²C (Inter-Integrated Circuit) braucht neben der Stromversorgung nur zwei Anschlüsse für die Datenübertragung, der SPI-Bus (Serial Peripheral Interface) fünf.

Die drei Größen und ihre Ansteuerung

Wir zeigen hier drei gängige Größen. Welcher Bus zum Einsatz kommt, hängt am verbauten Chipsatz:

  • 0,96 Zoll – Chipsatz SSD1306, Ansteuerung über I²C
  • 1,3 Zoll – Chipsatz SH1106, Ansteuerung über I²C
  • 2,42 Zoll – Chipsatz SSD1309, Ansteuerung über SPI
0,96 Zoll großes OLED-Display
0,96-Zoll-OLED – Ansteuerung über I²C
1,3 Zoll großes OLED-Display
1,3-Zoll-OLED – Ansteuerung über I²C
2,42 Zoll großes OLED-Display
2,42-Zoll-OLED – Ansteuerung über SPI
1 / 3

0,96-Zoll-OLED anschließen (I²C)

Über I²C brauchst du neben der Stromversorgung nur zwei Leitungen: SDA und SCL. Am Arduino UNO liegen sie auf A4 (SDA) und A5 (SCL).

Schaltplan mit 0,96-Zoll-OLED am Arduino UNO
Schaltplan: 0,96-Zoll-OLED am Arduino

2,42-Zoll-OLED anschließen (SPI)

Über SPI kommen fünf Leitungen zur Stromversorgung dazu:

  • GND – GND
  • VCC – 5V
  • SCK – Pin 13
  • SDA – Pin 11
  • RS – Pin 8 (Reset)
  • DC – Pin 9
  • CS – Pin 10

Diese drei Pins – 10, 9 und 8 – tauchen im Sketch in genau dieser Reihenfolge wieder auf, wenn das Display angelegt wird.

Schaltplan mit 2,42-Zoll-OLED über SPI am Arduino UNO
Schaltplan: 2,42-Zoll-OLED mit SSD1309 am Arduino

Bibliothek u8g2 installieren

Suche unter Sketch › Bibliothek einbinden › Bibliotheken verwalten nach der Bibliothek u8g2. Alternativ klickst du auf das Symbol der Bibliotheksverwaltung in der Seitenleiste.

Bibliotheksverwaltung der Arduino IDE mit der Bibliothek u8g2
Die Bibliothek u8g2 in der Bibliotheksverwaltung
Symbol der Bibliotheksverwaltung in der Arduino IDE
Alternativ über dieses Symbol in der Seitenleiste
1 / 2

Das Programm

Je nach Chipsatz musst du das Display in u8g2 unterschiedlich anlegen. Ersetze dazu im Sketch die erste Zeile nach dem include durch die passende Variante:

  • 0,96 Zoll, I²C (SSD1306): U8G2_SSD1306_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
  • 1,3 Zoll, I²C (SH1106): U8G2_SH1106_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
  • 2,42 Zoll, SPI (SSD1309): U8G2_SSD1309_128X64_NONAME2_1_4W_HW_SPI oled(U8G2_R0, 10, 9, 8);

Der Sketch führt nacheinander vor, was die Bibliothek kann: ein Bild als XBM, ein zufälliges Pixelmuster, Text in drei Schriftarten, Kreise, Rahmen, Linien und ausgefüllte Kreise. Jede Ansicht bleibt zwei Sekunden stehen.

Alle Zeichenfunktionen der Bibliothek u8g2 vorführen
#include "U8g2lib.h"

// 2,42 Zoll OLED initialisieren
U8G2_SSD1309_128X64_NONAME2_1_4W_HW_SPI oled(U8G2_R0, 10, 9, 8);

// Bildschirmgröße feststellen
int BildschirmBreite = oled.getDisplayWidth();
int BildschirmHoehe = oled.getDisplayHeight();

// Smiley als XBM, erstellt mit GIMP
#define SmileyBreite 46
#define SmileyHoehe 45
static unsigned char Smiley[] =
{
   0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00,
   0x00, 0xf0, 0x07, 0xf8, 0x03, 0x00, 0x00, 0xfc, 0x00, 0xc0, 0x0f, 0x00,
   0x00, 0x3e, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x7c, 0x00,
   0xc0, 0x07, 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xe0, 0x01,
   0xf0, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x70, 0x00, 0x00, 0x00, 0x80, 0x03,
   0x38, 0x7e, 0x00, 0x80, 0x1f, 0x07, 0x38, 0xff, 0x00, 0xc0, 0x3f, 0x07,
   0x9c, 0xff, 0x01, 0xc0, 0x3f, 0x0e, 0x9c, 0xe7, 0x01, 0xc0, 0x39, 0x0e,
   0x8e, 0xc3, 0x01, 0xc0, 0x30, 0x1c, 0x8e, 0xe3, 0x01, 0xc0, 0x31, 0x1c,
   0x86, 0xf7, 0x01, 0xc0, 0x3b, 0x18, 0x87, 0xff, 0x01, 0xc0, 0x3f, 0x38,
   0x07, 0xff, 0x00, 0x80, 0x3f, 0x38, 0x03, 0x7e, 0x00, 0x80, 0x1f, 0x30,
   0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30,
   0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30,
   0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30,
   0x07, 0x00, 0x00, 0x00, 0x00, 0x38, 0x07, 0x20, 0x00, 0x00, 0x01, 0x38,
   0x06, 0x70, 0x00, 0x80, 0x03, 0x18, 0x0e, 0xf0, 0x00, 0xc0, 0x01, 0x1c,
   0x0e, 0xe0, 0x03, 0xf0, 0x01, 0x1c, 0x1c, 0xc0, 0x3f, 0xfc, 0x00, 0x0e,
   0x1c, 0x80, 0xff, 0x7f, 0x00, 0x0e, 0x38, 0x00, 0xfc, 0x1f, 0x00, 0x07,
   0x38, 0x00, 0xc0, 0x03, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, 0x80, 0x03,
   0xf0, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe0, 0x01, 0x00, 0x00, 0xe0, 0x01,
   0xc0, 0x07, 0x00, 0x00, 0xf8, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x7c, 0x00,
   0x00, 0x3e, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xfc, 0x00, 0xc0, 0x0f, 0x00,
   0x00, 0xf0, 0x07, 0xf8, 0x03, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00,
   0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00
};

void setup()
{
  // Zufallsgenerator starten
  randomSeed(A0);

  // Display starten
  oled.begin();

  // Kontrast, maximal 255
  oled.setContrast(200);
}

void loop()
{
  // Farbe weiß
  oled.setDrawColor(1);

  // Smiley
  oled.firstPage();
  do
  {
    oled.drawXBM(40, 10, SmileyBreite, SmileyHoehe, Smiley);
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // Pixelmuster
  oled.firstPage();
  do
  {
    for (int i = 0; i < 500; i++)
    {
      int x = random(1, BildschirmBreite);
      int y = random(1, BildschirmHoehe);
      oled.drawPixel(x, y);
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // Text zeigen
  oled.firstPage();
  do
  {
    oled.setFontDirection(0);

    // Schriftart wechseln
    oled.setFont(u8g2_font_unifont_t_symbols);
    oled.setCursor(2, 10);
    oled.print("Text");

    // Schriftart wechseln
    oled.setFont(u8g2_font_helvB14_tf);
    oled.setCursor(2, 30);
    oled.print("Text");

    // Schriftart wechseln
    oled.setFont(u8g2_font_courB24_tf);
    oled.setCursor(2, 60);
    oled.print("Text");
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // Kreise
  oled.firstPage();
  do
  {
    for (int i = 2; i < BildschirmHoehe / 2; i += 3)
    {
      oled.drawCircle(BildschirmBreite / 2, BildschirmHoehe / 2, i);
      delay(10);
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // Rahmen
  oled.firstPage();
  do
  {
    for (int i = 2; i < BildschirmHoehe; i += 10)
    {
      oled.drawFrame(0, 0, i, i);
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // vertikale Linien
  oled.firstPage();
  do
  {
    for (int i = 0; i < BildschirmBreite; i += 4)
    {
      oled.drawVLine(i, 0, BildschirmBreite - 1);
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // horizontale Linien
  oled.firstPage();
  do
  {
    for (int i = 0; i < BildschirmHoehe; i += 4)
    {
      oled.drawHLine(0, i, BildschirmBreite - 1);
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // ausgefüllte Kreise
  oled.firstPage();
  do
  {
    int Radius = 5;
    int StartX = 10;
    int StartY = 10;
    while (StartX < BildschirmBreite - Radius)
    {
      for (int i = StartY; i < BildschirmBreite - Radius; i += 20)
      {
        oled.drawDisc(StartX, i, Radius);
      }
      StartX += 10;
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();

  // Linien
  oled.firstPage();
  do
  {
    for (int i = 0; i < BildschirmBreite; i += 5)
    {
      oled.drawLine(0, i, 128, 64);
    }
    for (int i = BildschirmBreite; i > 0; i -= 5)
    {
      oled.drawLine(BildschirmBreite, i, 0, 0);
    }
  }
  while (oled.nextPage());
  delay(2000);
  oled.clearDisplay();
}
Calificar la guía

Comentarios

Haz una pregunta o comparte tu experiencia

Schreib uns, wenn etwas nicht funktioniert. Nenne dabei dein Board und die Fehlermeldung.

Revisamos cada comentario antes de publicarlo. Tu dirección de correo electrónico permanece con nosotros.