Skip to content

SH1106 OLED displej – kompletní tahák

Popis

SH1106 je řadič monochromatických OLED displejů (typicky 128×64 px). Používá se v embedded systémech pro zobrazování textu, grafiky, menu a stavových informací.

Podporuje:

  • I2C
  • SPI

POZOR: často se zaměňuje za SSD1306 → není plně kompatibilní.


Vlastnosti

  • 128×64 px (interně 132×64)
  • monochromatický
  • nízká spotřeba
  • vysoký kontrast
  • vhodný pro Arduino / ESP32 / STM32

Rozdíl vs SSD1306

  • jiná paměť (offset sloupců)
  • obraz může být posunutý
  • nutná jiná knihovna

Typický problém:

  • I2C OK
  • displej nic nezobrazuje

Protokoly

I2C

Piny:

  • VCC
  • GND
  • SDA
  • SCL

Adresa:

  • 0x3C
  • 0x3D

SPI

  • rychlejší
  • více pinů

Knihovny

U8g2

cpp
#include <Arduino.h>
#include <Wire.h>
#include <U8g2lib.h>
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);

Adafruit SH110X

cpp
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire);

Inicializace

U8g2

cpp
u8g2.begin();

Adafruit

cpp
display.begin(0x3C, true);
display.clearDisplay();
display.display();

Syntaxe

U8g2

cpp
u8g2.clearBuffer(); // Vymaže interní framebuffer (RAM), do kterého se kreslí

u8g2.setFont(u8g2_font_ncenB08_tr);     // Nastaví font pro vykreslování textu     
          u8g2.setFont(u8g2_font_ncenB08_tr);  // malý font
          u8g2.setFont(u8g2_font_ncenB14_tr);  // větší font
          u8g2.setFont(u8g2_font_logisoso32_tr); // hodně velký font

u8g2.drawStr(x, y, "Text");   // Vykreslí text na pozici (x, y)
                              // POZOR: y je baseline textu (ne horní okraj)

u8g2.drawLine(x1, y1, x2, y2);          // Vykreslí čáru mezi dvěma body (x1, y1) → (x2, y2)

u8g2.drawFrame(x, y, w, h);   // Vykreslí prázdný obdélník (jen obrys)
                              // x, y = levý horní roh
                              // w = šířka, h = výška

u8g2.drawBox(x, y, w, h);     // Vykreslí vyplněný obdélník

u8g2.drawCircle(x, y, r);     // Vykreslí kružnici se středem (x, y) a poloměrem r

u8g2.drawXBMP(x, y, w, h, bitmap);      // Vykreslí bitmapu (obrázek)
                                        // x, y = pozice
                                        // w, h = rozměry
                                        // bitmap = pole dat (obvykle PROGMEM)

u8g2.sendBuffer();  // Odešle obsah framebufferu na displej (bez toho se nic nezobrazí!)

Adafruit

cpp
display.clearDisplay();       // Vymaže obsah interního framebufferu (RAM)
display.setCursor(x, y);      // Nastaví pozici kurzoru pro text (levý horní roh textu)      
display.setTextSize(1);       // Nastaví velikost textu (1 = základní velikost, 2 = 2× větší, atd.)
display.setTextColor(SH110X_WHITE);     // Nastaví barvu textu (u monochrom OLED jen WHITE = zapnutý pixel)
display.print("Text");        // Vypíše text bez odřádkování
display.println("Text");      // Vypíše text a přejde na další řádek

display.drawPixel(x, y, SH110X_WHITE);            // Vykreslí jeden pixel na pozici (x, y)
display.drawLine(x1, y1, x2, y2, SH110X_WHITE);   // Vykreslí čáru mezi body (x1, y1) → (x2, y2)
display.drawRect(x, y, w, h, SH110X_WHITE);       // Vykreslí obdélník (jen obrys)
                                                  // x, y = levý horní roh
                                                  // w = šířka, h = výška   
display.fillRect(x, y, w, h, SH110X_WHITE);       // Vykreslí vyplněný obdélník
display.drawCircle(x, y, r, SH110X_WHITE);        // Vykreslí kružnici se středem (x, y) a poloměrem r
display.drawBitmap(x, y, bitmap, w, h, SH110X_WHITE);       // Vykreslí bitmapu (obrázek)
                                                            // bitmap = pole dat (často uložené v PROGMEM)

display.display();  // Odešle obsah framebufferu na displej
                    // BEZ toho se nic nezobrazí!

Příklady

Text

cpp
display.clearDisplay();
display.setCursor(0, 10);     // Nastaví pozici kurzoru pro text
                              // (0,10) = levý okraj, 10 px odshora
display.println("Ahoj");      // Vypíše text "Ahoj" na aktuální pozici
                              // println zároveň posune kurzor na další řádek
display.display();            // Odešle data z bufferu na displej
                              // → bez toho by se text nezobrazil!

Více řádků

cpp
display.setCursor(0, 10);
display.println("Teplota: 24C");
display.setCursor(0, 25);
display.println("Vlhkost: 50%");

Grafika

cpp
display.drawRect(0,0,128,64,SH110X_WHITE);        // Vykreslí obdélník (jen obrys) přes celý displej
                                                  // (0,0) = levý horní roh
                                                  // 128 = šířka displeje
                                                  // 64 = výška displeje
                                                  // → vytvoří rámeček kolem celé obrazovky     

display.drawCircle(64,32,10,SH110X_WHITE);        // (0,0) = levý horní roh
                                                  // 128 = šířka displeje
                                                  // 64 = výška displeje
                                                  // → vytvoří rámeček kolem celé obrazovky

Progress bar

cpp
display.drawRect(10,25,100,10,SH110X_WHITE);
display.fillRect(12,27,80,6,SH110X_WHITE);

Animace

cpp
for(int x=0;x<128;x++){                 // Smyčka od 0 do 127 (šířka displeje = 128 px)
 display.clearDisplay();                // Vymaže předchozí snímek (aby se pixel "nehromadil")
 display.drawPixel(x,32,SH110X_WHITE);      // Vykreslí jeden pixel
                                            // x = aktuální pozice ve smyčce (posouvá se doprava)
                                            // y = 32 → střed displeje (výška 64 → polovina je 32)
 display.display();           // Odešle obraz na displej (vykreslí snímek)
 delay(10);                   // Krátká pauza → zpomalí animaci
}

Grafika

  • pixel
  • čára
  • obdélník
  • kružnice
  • bitmapa
  • progress bar
  • UI

Typické použití

  • IoT
  • senzory
  • debug
  • menu
  • měření

Poznámky

  • často špatně označeno jako SSD1306
  • nejčastější chyba = špatná knihovna
  • I2C adresa většinou 0x3C
  • nutné pull-up rezistory
  • framebuffer princip

I2C scanner

cpp
#include <Wire.h>

void setup(){
 Wire.begin();
 Serial.begin(115200);
}

void loop(){
 for(byte a=1;a<127;a++){
  Wire.beginTransmission(a);
  if(Wire.endTransmission()==0){
   Serial.println(a,HEX);
  }
 }
 delay(3000);
}