OLED displeje se dnes dají koupit v mnoha různých velikostech. Tentokrát se podívám na jednu z nejmenších běžně dostupných variant s úhlopříčkou 0,91 palce a rozlišením 128 × 32 pixelů.
Displej je opravdu drobný a kvůli malé výšce se na něj nevejde příliš mnoho informací. Právě jeho podlouhlý tvar ale může být v některých projektech výhodou. Hodí se například pro zobrazení času, teploty, stavu zařízení, výsledku měření nebo několika položek jednoduchého menu.
Modul komunikuje pomocí sběrnice I²C, takže kromě napájení potřebuje pouze dva vodiče pro komunikaci. Díky tomu se snadno připojuje k Arduinu, ESP nebo dalším vývojovým deskám.
V článku si ukážeme zapojení displeje, instalaci potřebné knihovny a několik programů pro zobrazení textu i jednoduché grafiky.


Jak OLED displej funguje
Zkratka OLED pochází z anglického označení Organic Light-Emitting Diode. Na rozdíl od běžného LCD displeje nepotřebuje OLED samostatné podsvícení. Každý rozsvícený bod totiž vytváří vlastní světlo.
Vypnuté pixely zůstávají černé, zatímco zapnuté pixely u tohoto modulu svítí bíle. Díky tomu má displej výrazný kontrast a zůstává dobře čitelný i při velmi malých rozměrech.
Jednotlivé pixely můžeme ovládat samostatně. Displej proto není omezený pouze na předem připravené znaky, ale dokáže zobrazovat také čáry, rámečky, symboly, jednoduché obrázky nebo malé grafy.
Rozlišení 128 × 32 pixelů
Displej má 128 obrazových bodů na šířku a pouze 32 bodů na výšku. Oproti častějším OLED displejům s rozlišením 128 × 64 pixelů má tedy poloviční výšku.
To je potřeba zohlednit při návrhu obrazovky. Velký text může zabrat téměř celou výšku displeje, zatímco při použití menšího písma lze zobrazit několik krátkých řádků.
Displej se proto nejlépe hodí pro stručné informace, například:
- Aktuální teplotu nebo vlhkost
- Čas a datum
- Stav připojení
- Napětí akumulátoru
- Výsledek měření
- Krátké zprávy
- Jednoduché menu
- Malý průběhový graf
Na rozsáhlejší nabídky nebo větší množství textu už je vhodnější displej s rozlišením 128 × 64 pixelů.
Řadič SSD1306
O řízení displeje se stará integrovaný obvod SSD1306. Ten přijímá data z Arduina a podle nich ovládá jednotlivé pixely OLED panelu.
SSD1306 je velmi rozšířený řadič, takže pro něj existuje několik hotových Arduino knihoven. Nemusíme proto ručně vytvářet příkazy pro ovládání jednotlivých pixelů. Knihovna se postará o komunikaci s displejem a nabídne funkce pro vykreslení textu, čar, rámečků nebo obrázků.
V tomto článku použiji knihovnu U8g2, se kterou jsem pracoval také u dalších OLED displejů. Podporuje řadič SSD1306, obsahuje velké množství písem a nabízí jednoduché funkce pro kreslení grafiky.
Komunikace pomocí I²C
Displej komunikuje pomocí sběrnice I²C. Pro přenos dat se používají dva vodiče:
- SCL – hodinový signál
- SDA – přenos dat
K nim je potřeba připojit ještě napájení VCC a zem GND. Celý displej tedy používá pouze čtyři vývody.
Výhodou I²C je, že stejné vodiče mohou používat také další moduly. K Arduinu tak můžeme současně připojit například OLED displej, teplotní čidlo a hodiny reálného času, aniž by každý modul potřeboval vlastní dvojici komunikačních pinů.
Jednotlivá zařízení se na společné sběrnici rozlišují pomocí I²C adres. Přesnou adresu konkrétního displeje si později ověříme pomocí jednoduchého I²C scanneru.
Základní parametry
- Typ displeje: OLED
- Úhlopříčka: 0,91 palce
- Rozlišení: 128 × 32 pixelů
- Barva obrazu: modrá
- Řadič: SSD1306
- Komunikační rozhraní: I²C
- Napájecí napětí: 3,3 až 5 V
- Počet vývodů: 4
Díky napájecímu rozsahu od 3,3 do 5 V lze modul použít jak s klasickými 5 V deskami Arduino, tak s deskami používajícími 3,3 V.
Vývody modulu
Na modulu jsou vyvedené čtyři piny:
| Vývod | Funkce |
|---|---|
| GND | Zem napájení |
| VCC | Napájecí napětí 3,3 až 5 V |
| SCK / SCL | Hodinový signál sběrnice I²C |
| SDA | Datový signál sběrnice I²C |
Zapojení displeje k Arduinu
Pro první vyzkoušení připojím displej k Arduinu Uno. Protože modul komunikuje pomocí sběrnice I²C, potřebujeme kromě napájení pouze vodiče SDA a SCL.
Zapojení bude následující:
| OLED displej | Arduino Uno |
|---|---|
| GND | GND |
| VCC | 5 V |
| SCL / SCK | A5 |
| SDA | A4 |

Piny A4 a A5 jsou u Arduina Uno určené pro komunikaci I²C. U novějších verzí desky jsou signály SDA a SCL vyvedené také na samostatných pinech vedle AREF. Elektricky jsou ale propojené se stejnými piny A4 a A5.
Displej lze napájet také napětím 3,3 V. To se hodí při použití s deskami ESP nebo Raspberry Pi. U každé vývojové desky je ale potřeba ověřit, na kterých pinech má vyvedenou sběrnici I²C.
Kontrola I²C adresy
Každé zařízení připojené ke sběrnici I²C má vlastní adresu. Arduino podle této adresy pozná, se kterým modulem právě komunikuje.
U OLED displejů s řadičem SSD1306 se často používá adresa 0x3C. Nelze ale spoléhat na to, že ji mají všechny vyráběné varianty stejnou. Proto je dobré adresu před prvním spuštěním ověřit pomocí programu I²C scanner.
Program postupně vyzkouší všechny možné adresy a nalezená zařízení vypíše do sériového monitoru.
///////////////////////I2C scanner fw v.0.1 /////////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
byte chyba = 0; //výsledek pokusu o komunikaci
byte adresa = 0; //právě testovaná I2C adresa
byte pocet = 0; //počet nalezených zařízení
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
Wire.begin(); //start sběrnice I2C
Serial.begin(9600); //start sériové linky
delay(1000); //krátká pauza po spuštění
Serial.println(F("I2C scanner"));
Serial.println(F("Hledam zarizeni..."));
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
hledatZarizeni(); //prohledej I2C sběrnici
delay(5000); //další kontrola za 5 sekund
}
/////////////////////////////hledání zařízení//////////////////////////////////////////////////////////////////////////////////
void hledatZarizeni()
{
pocet = 0; //vynuluj počet zařízení
for(adresa = 1; adresa < 127; adresa++)
{
Wire.beginTransmission(adresa); //zkus zahájit komunikaci
chyba = Wire.endTransmission(); //ukonči komunikaci a načti výsledek
if(chyba == 0) //pokud zařízení odpovědělo
{
Serial.print(F("Nalezeno zarizeni na adrese 0x"));
if(adresa < 16) //doplň úvodní nulu
{
Serial.print(F("0"));
}
Serial.println(adresa, HEX); //vypiš adresu
pocet++; //zvyš počet zařízení
}
}
if(pocet == 0) //pokud nebylo nic nalezeno
{
Serial.println(F("Zadne I2C zarizeni nebylo nalezeno"));
}
else //pokud bylo zařízení nalezeno
{
Serial.print(F("Pocet nalezenych zarizeni: "));
Serial.println(pocet);
}
Serial.println();
}
Po nahrání programu otevřeme sériový monitor a nastavíme rychlost 9600 baudů. Pokud je displej správně zapojený, měla by se objevit nalezená adresa.

Pokud program žádné zařízení nenajde, je potřeba zkontrolovat napájení, propojení země a vodiče SDA a SCL. Častou chybou bývá právě prohození datového a hodinového vodiče.
Instalace knihovny U8g2
Pro ovládání displeje použiju knihovnu U8g2. Je to univerzální knihovna pro spoustu monochromatických displejů a podporuje i řadič SSD1306.
Instalace v Arduino IDE:
- Otevřít Manažéra knihoven
- Vyhledat U8g2
- Nainstalovat knihovnu U8g2 od oliver
- Restartovat Arduino IDE, pokud by se příklady nebo knihovna nenačetly správně
Knihovna obsahuje velké množství konstruktorů pro různé typy displejů. Pro tento modul s řadičem SSD1306, rozlišením 128 × 32 pixelů a hardwarovou komunikací I²C použijeme:
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
Označení jednotlivých částí konstruktoru znamená:
- SSD1306 – použitý řadič displeje
- 128X32 – rozlišení displeje
- UNIVISION – varianta zapojení displeje
- F – použití celé obrazové paměti
- HW_I2C – hardwarová komunikace I²C
Varianta s celou obrazovou pamětí umožňuje nejprve připravit celý obraz v paměti Arduina a potom ho najednou odeslat na displej. Pro obraz o rozlišení 128 × 32 pixelů je potřeba 512 bajtů paměti.
První program
První program pouze inicializuje displej a zobrazí na něm dva řádky textu. Tím jednoduše ověříme, že je správně zapojený a že jsme zvolili vhodný konstruktor knihovny.
///////////////////////OLED 128x32 fw v.0.1 /////////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
vypisUvod(); //zobraz úvodní text
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
//obraz zůstává na displeji, hlavní smyčka nemusí nic dělat
}
/////////////////////////////výpis úvodního textu/////////////////////////////////////////////////////////////////////////////
void vypisUvod()
{
displej.clearBuffer(); //vymaž obrazovou paměť
displej.setFont(u8g2_font_6x12_tf); //nastav písmo
displej.drawStr(0, 12, "Michaluv brloh"); //první řádek
displej.drawStr(0, 28, "OLED 128x32"); //druhý řádek
displej.sendBuffer(); //odešli obraz na displej
}

Po zapnutí programu se nejprve pomocí příkazu displej.begin() inicializuje displej. Funkce vypisUvod() potom připraví celý obraz a odešle ho na OLED.
Příkaz:
displej.clearBuffer();
vymaže obrazovou paměť. Bez jeho použití by v ní mohly zůstat části předchozího obrazu.
Následující řádek nastaví použité písmo:
displej.setFont(u8g2_font_6x12_tf);
Písmo u8g2_font_6x12_tf má přibližnou velikost 6 × 12 pixelů a na malý displej se dobře hodí.
Text vykreslíme pomocí funkce:
displej.drawStr(0, 12, "Michaluv brloh");
První číslo určuje vodorovnou souřadnici, druhé číslo svislou souřadnici a posledním parametrem je zobrazovaný text.
Souřadnice [0, 0] se nachází v levém horním rohu displeje. U funkce drawStr() ale svislá souřadnice neurčuje horní okraj znaků, nýbrž základní linku textu. Proto první řádek nezačíná na souřadnici Y rovné nule.
Nakonec je potřeba připravený obraz skutečně odeslat na displej:
displej.sendBuffer();
Dokud tuto funkci nezavoláme, změny provedené v obrazové paměti se na displeji neprojeví.
Obnovování obrazu
V prvním programu se obraz vykreslí pouze jednou ve funkci setup(). To stačí pro neměnný text, který má zůstat na displeji po celou dobu provozu.
Pokud chceme zobrazovat měnící se hodnoty, například teplotu nebo čas, musíme celý obraz pravidelně překreslovat.
Postup je vždy stejný:
- Vymazat obrazovou paměť
- Nakreslit nový obsah
- Odeslat obraz na displej
Základ překreslování může vypadat například takto:
displej.clearBuffer(); //vymaž starý obraz
//sem přijde vykreslení nového obsahu
displej.sendBuffer(); //zobraz nový obraz
Vymazání paměti je důležité hlavně při zobrazování čísel. Kdybychom například změnili hodnotu 100 na 99 bez smazání starého obrazu, mohla by na displeji zůstat část poslední číslice.
OLED displej nepotřebuje neustálé obnovování jako některé jiné zobrazovací technologie. Jakmile obraz odešleme, zůstane zobrazený až do další změny nebo vypnutí napájení.
Výběr písma
Knihovna U8g2 obsahuje velké množství písem různých velikostí. Na displeji s výškou pouze 32 pixelů je ale potřeba vybírat opatrně. Příliš velké písmo se může na obrazovku vejít jen částečně.
Písmo nastavíme příkazem:
displej.setFont(u8g2_font_6x12_tf);
Použité písmo zůstává nastavené, dokud ho nezměníme dalším příkazem setFont().
Pro malý displej se mohou hodit například tato písma:
displej.setFont(u8g2_font_5x7_tf); //malé písmo

displej.setFont(u8g2_font_6x12_tf); //dobře čitelné písmo

displej.setFont(u8g2_font_9x15_tf); //větší písmo

displej.setFont(u8g2_font_logisoso24_tf); //velké číslice

Názvy písem mohou na první pohled působit nepřehledně. Část názvu obvykle napovídá přibližnou velikost nebo vzhled písma.
Přehled dostupných písem je součástí dokumentace knihovny U8g2. Nejjednodušší je ale několik vhodných písem vyzkoušet přímo na displeji.
Zarovnání textu na střed
Funkce drawStr() vykresluje text od zadané vodorovné souřadnice směrem doprava. Pokud chceme text umístit doprostřed displeje, musíme nejprve zjistit jeho šířku.
K tomu slouží funkce:
displej.getStrWidth(text);
Vodorovnou souřadnici potom vypočítáme takto:
x = (128 - sirkaTextu) / 2;
Od celkové šířky displeje odečteme šířku textu a zbývající prostor rozdělíme na dvě poloviny.
Následující program zobrazí oba řádky přesně uprostřed displeje:
///////////////////////OLED zarovnani textu fw v.0.1 ////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
const char text1[] = "Michaluv brloh"; //text prvního řádku
const char text2[] = "OLED 128x32"; //text druhého řádku
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
vypisText(); //zobraz text
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
//obraz se nemění
}
/////////////////////////////výpis textu///////////////////////////////////////////////////////////////////////////////////////
void vypisText()
{
int x1; //pozice prvního textu
int x2; //pozice druhého textu
displej.clearBuffer(); //vymaž obrazovou paměť
displej.setFont(u8g2_font_6x12_tf); //nastav písmo
x1 = (128 - displej.getStrWidth(text1)) / 2; //vypočítej střed
x2 = (128 - displej.getStrWidth(text2)) / 2; //vypočítej střed
displej.drawStr(x1, 12, text1); //zobraz první řádek
displej.drawStr(x2, 28, text2); //zobraz druhý řádek
displej.sendBuffer(); //odešli obraz na displej
}

Tento způsob funguje pro libovolně dlouhý text, pokud se samozřejmě celý vejde na displej.
Zobrazení proměnné
Při praktickém použití většinou nezobrazujeme pouze pevný text, ale také hodnoty uložené v proměnných. Může jít například o teplotu, napětí, počet impulzů nebo stav počítadla.
Funkce drawStr() ale očekává textový řetězec. Číselnou hodnotu proto musíme nejprve převést na text.
Pro převod celého čísla lze použít funkci snprintf():
snprintf(text, sizeof(text), "%d", hodnota);
Proměnná hodnota se převede na text a uloží do znakového pole text.
Velká hodnota na displeji
Následující program zobrazuje velké počítadlo, které se každou sekundu zvýší o jedničku. Nad hodnotou je menším písmem zobrazený popisek.
Program zároveň ukazuje, jak lze během jednoho vykreslení použít dvě různá písma.
///////////////////////OLED pocitadlo fw v.0.1 //////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
unsigned int pocitadlo = 0; //aktuální hodnota počítadla
char textHodnoty[10]; //textová podoba hodnoty
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
vypisHodnotu(); //zobraz aktuální hodnotu
pocitadlo++; //zvyš počítadlo
delay(1000); //počkej jednu sekundu
}
/////////////////////////////výpis hodnoty/////////////////////////////////////////////////////////////////////////////////////
void vypisHodnotu()
{
int x; //vodorovná pozice hodnoty
snprintf(textHodnoty, sizeof(textHodnoty), "%u", pocitadlo); //převeď číslo na text
displej.clearBuffer(); //vymaž obrazovou paměť
displej.setFont(u8g2_font_5x7_tf); //nastav malé písmo
displej.drawStr(0, 7, "Pocitadlo"); //zobraz popisek
displej.setFont(u8g2_font_logisoso24_tf); //nastav velké písmo
x = (128 - displej.getStrWidth(textHodnoty)) / 2; //vypočítej střed
displej.drawStr(x, 32, textHodnoty); //zobraz hodnotu
displej.sendBuffer(); //odešli obraz na displej
}
Velké číslice využijí téměř celou výšku displeje. Malý popisek se ještě vejde do horní části obrazovky.
Při větším počtu číslic je potřeba počítat s tím, že se hodnota nemusí vejít na displej. V takovém případě můžeme použít menší písmo nebo zobrazovanou hodnotu upravit.
Kreslení jednoduché grafiky
Knihovna U8g2 neumí pouze text. Nabízí také funkce pro kreslení základních geometrických tvarů.
Mezi nejčastěji používané patří:
displej.drawPixel(x, y); //nakreslí jeden pixel
displej.drawLine(x1, y1, x2, y2); //nakreslí čáru
displej.drawFrame(x, y, w, h); //nakreslí obrys obdélníku
displej.drawBox(x, y, w, h); //nakreslí vyplněný obdélník
displej.drawCircle(x, y, r); //nakreslí kružnici
displej.drawDisc(x, y, r); //nakreslí vyplněný kruh
Souřadnice [0, 0] se nachází v levém horním rohu displeje. Hodnota X se zvětšuje směrem doprava a hodnota Y směrem dolů.
Poslední viditelný pixel má souřadnici:
X = 127
Y = 31
Při kreslení je tedy potřeba hlídat, aby objekty nepřesahovaly mimo plochu displeje.
Ukázka jednoduché grafiky
Následující program nakreslí rámeček kolem displeje, oddělovací čáru, kružnici a několik vyplněných obdélníků.
///////////////////////OLED grafika fw v.0.1 ////////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
nakresliGrafiku(); //zobraz ukázkovou grafiku
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
//obraz se nemění
}
/////////////////////////////vykreslení grafiky///////////////////////////////////////////////////////////////////////////////
void nakresliGrafiku()
{
displej.clearBuffer(); //vymaž obrazovou paměť
displej.drawFrame(0, 0, 128, 32); //rámeček kolem displeje
displej.drawLine(63, 1, 63, 30); //svislá oddělovací čára
displej.drawCircle(31, 16, 10); //nakresli kružnici
displej.drawDisc(31, 16, 3); //nakresli střed kružnice
displej.drawBox(73, 23, 8, 6); //první sloupec
displej.drawBox(85, 18, 8, 11); //druhý sloupec
displej.drawBox(97, 12, 8, 17); //třetí sloupec
displej.drawBox(109, 6, 8, 23); //čtvrtý sloupec
displej.sendBuffer(); //odešli obraz na displej
}

Grafické funkce se hodí například pro tvorbu ikon, ukazatelů stavu, jednoduchých grafů nebo vlastního uživatelského rozhraní.
Ukazatel průběhu
Jednoduchý ukazatel průběhu můžeme vytvořit kombinací obrysu a vyplněného obdélníku.
Nejprve nakreslíme rámeček:
displej.drawFrame(4, 18, 120, 12);
Do něj potom vložíme vyplněnou část:
displej.drawBox(6, 20, sirka, 8);
Šířku vyplněné části lze vypočítat z hodnoty v procentech:
sirka = map(procenta, 0, 100, 0, 116);
Funkce map() převede rozsah od 0 do 100 procent na šířku od 0 do 116 pixelů.
Praktický ukazatel v procentech
Následující program zobrazuje procentuální hodnotu a pod ní jednoduchý ukazatel průběhu. Hodnota postupně roste od 0 do 100 procent a potom začne znovu od začátku.
///////////////////////OLED ukazatel fw v.0.1 ///////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
byte procenta = 0; //aktuální hodnota v procentech
char textProcent[8]; //textová podoba hodnoty
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
vypisUkazatel(); //zobraz hodnotu a ukazatel
procenta += 1; //zvyš hodnotu
if(procenta > 100) //pokud hodnota překročila 100 %
{
procenta = 0; //začni znovu od nuly
}
delay(150); //krátká pauza
}
/////////////////////////////výpis ukazatele///////////////////////////////////////////////////////////////////////////////////
void vypisUkazatel()
{
byte sirka; //šířka vyplněné části
int x; //vodorovná pozice textu
snprintf(textProcent, sizeof(textProcent), "%u %%", procenta); //vytvoř text
sirka = map(procenta, 0, 100, 0, 116); //přepočítej procenta na pixely
displej.clearBuffer(); //vymaž obrazovou paměť
displej.setFont(u8g2_font_6x12_tf); //nastav písmo
x = (128 - displej.getStrWidth(textProcent)) / 2; //vypočítej střed
displej.drawStr(x, 11, textProcent); //zobraz procenta
displej.drawFrame(4, 18, 120, 12); //nakresli obrys ukazatele
if(sirka > 0) //pokud je co vykreslit
{
displej.drawBox(6, 20, sirka, 8); //nakresli vyplněnou část
}
displej.sendBuffer(); //odešli obraz na displej
}
Podobný ukazatel lze použít například pro stav nabití akumulátoru, sílu signálu, naplnění zásobníku nebo průběh dlouhé operace.
Jednoduchá animace
OLED displej dokáže obraz překreslovat dostatečně rychle také pro jednoduché animace. Princip je stále stejný. Nejprve vymažeme obrazovou paměť, nakreslíme objekt na nové pozici a celý obraz odešleme na displej.
Následující program zobrazuje malou tečku, která se pohybuje zleva doprava a po dosažení okraje se vrátí zpět.
///////////////////////OLED animace fw v.0.1 ////////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
int poziceX = 3; //vodorovná pozice tečky
int smer = 1; //směr pohybu
unsigned long posledniPohyb = 0; //čas posledního překreslení
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
animace(); //obsluhuj animaci
}
/////////////////////////////animace///////////////////////////////////////////////////////////////////////////////////////////
void animace()
{
if(millis() - posledniPohyb >= 20) //pokud uplynulo 20 ms
{
posledniPohyb = millis(); //ulož čas překreslení
displej.clearBuffer(); //vymaž obrazovou paměť
displej.drawFrame(0, 0, 128, 32); //nakresli rámeček
displej.drawDisc(poziceX, 16, 3); //nakresli pohybující se tečku
displej.sendBuffer(); //odešli obraz na displej
poziceX = poziceX + smer; //posuň tečku
if(poziceX >= 124) //pokud dorazila doprava
{
smer = -1; //změň směr doleva
}
if(poziceX <= 3) //pokud dorazila doleva
{
smer = 1; //změň směr doprava
}
}
}
Časování je v tomto případě řešené pomocí funkce millis(). Program proto nemusí čekat v blokujícím příkazu delay() a během animace může současně obsluhovat tlačítka, měřit senzory nebo komunikovat s dalšími moduly.
Interval 20 ms odpovídá teoreticky až 50 překreslením za sekundu. Skutečná rychlost ale závisí také na době potřebné k odeslání celé obrazové paměti po sběrnici I²C.
U jednoduchých animací není potřeba používat maximální možnou rychlost. Příliš časté překreslování zbytečně zatěžuje Arduino i sběrnici. Pro stavové symboly nebo pomalejší pohyb často stačí interval 50 až 200 ms.
Zobrazení vlastního obrázku
Kromě textu a základních geometrických tvarů můžeme na displeji zobrazit také vlastní obrázek.
Protože jde o monochromatický displej, každý pixel může být pouze zapnutý nebo vypnutý. Obrázek tedy neobsahuje odstíny šedi ani barvy. Musí být předem převedený na černobílou bitmapu.
Knihovna U8g2 dokáže pracovat například s formátem XBM. Obrazová data jsou uložená přímo v programu jako pole bajtů.
Následující ukázka obsahuje jednoduchou ikonu akumulátoru o velikosti 16 × 16 pixelů.
///////////////////////OLED bitmapa fw v.0.1 ////////////////////////////////
///////////////////////14.7.2026 ///////////////////////////////////////////
///////////////////////www.michaluvbrloh.cz//////////////////////////////////
#include <Wire.h> //komunikace po sběrnici I2C
#include <U8g2lib.h> //ovládání OLED displeje
//OLED displej SSD1306 128x32 připojený pomocí hardwarové I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C displej(U8G2_R0, U8X8_PIN_NONE);
//ikona akumulátoru 16x16 pixelů
static const unsigned char baterie_bits[] U8X8_PROGMEM =
{
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0xFE, 0x3F,
0x02, 0x20,
0xFA, 0x27,
0xFA, 0xE7,
0xFA, 0xE7,
0xFA, 0xE7,
0xFA, 0xE7,
0xFA, 0x27,
0x02, 0x20,
0xFE, 0x3F,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00
};
/////////////////////////////po spuštění///////////////////////////////////////////////////////////////////////////////////////
void setup()
{
displej.begin(); //spusť OLED displej
vypisBaterii(); //zobraz ikonu a hodnotu
}
/////////////////////////////hlavní smyčka/////////////////////////////////////////////////////////////////////////////////////
void loop()
{
//obraz se nemění
}
/////////////////////////////výpis stavu baterie//////////////////////////////////////////////////////////////////////////////
void vypisBaterii()
{
displej.clearBuffer(); //vymaž obrazovou paměť
displej.drawXBMP(4, 8, 16, 16, baterie_bits); //zobraz ikonu baterie
displej.setFont(u8g2_font_9x15_tf); //nastav větší písmo
displej.drawStr(28, 21, "75 %"); //zobraz stav baterie
displej.sendBuffer(); //odešli obraz na displej
}

Funkce pro zobrazení bitmapy má následující tvar:
displej.drawXBMP(x, y, sirka, vyska, obrazovaData);
První dvě hodnoty určují pozici levého horního rohu obrázku. Následuje jeho šířka, výška a název pole obsahujícího obrazová data.
V tomto příkladu se ikona vykreslí na souřadnici [4, 8]:
displej.drawXBMP(4, 8, 16, 16, baterie_bits);
Obrázek zabírá plochu 16 × 16 pixelů a vedle něj zůstává dost prostoru pro zobrazení textové hodnoty.
Příprava vlastní bitmapy
Vlastní obrázek lze připravit v grafickém programu nebo pomocí převodníku bitmap do formátu vhodného pro Arduino.
Při přípravě je potřeba dodržet několik pravidel:
- Obrázek musí být černobílý
- Jeho rozměry nesmí překročit 128 × 32 pixelů
- Jednoduché tvary bývají na malém displeji čitelnější
- Tenké čáry mohou při zmenšení zaniknout
- Velká bitmapa zabere více paměti programu
Celá obrazovka o rozlišení 128 × 32 pixelů potřebuje:
128 × 32 ÷ 8 = 512 bajtů
Jeden bajt obsahuje stav osmi pixelů. Malé ikony proto zabírají pouze několik desítek bajtů, zatímco obrázek přes celou obrazovku potřebuje přibližně půl kilobajtu paměti programu.
U klasického Arduina Uno nebo Nano není jedna bitmapa problém. Pokud bychom ale do programu vložili velké množství obrázků nebo jednotlivé snímky animace, mohla by se rychle zaplnit paměť programu.
Animace z několika obrázků
Jednoduchou animaci lze vytvořit také střídáním několika bitmap. Každá bitmapa představuje jeden snímek.
Program postupně zobrazí například:
displej.drawXBMP(0, 0, 128, 32, obrazek1);
displej.sendBuffer();
delay(100);
displej.clearBuffer();
displej.drawXBMP(0, 0, 128, 32, obrazek2);
displej.sendBuffer();
Tento způsob se hodí pro malé symboly, blikající ikony nebo krátké úvodní animace. U většího počtu snímků je ale potřeba hlídat velikost programu.
Pro plynulý pohyb jednoduchých objektů je většinou výhodnější měnit jejich souřadnice než ukládat každý snímek jako samostatný obrázek.
Nastavení kontrastu
Jas displeje lze částečně ovlivnit nastavením kontrastu. K tomu slouží funkce:
displej.setContrast(100);
Použitá hodnota může být v rozsahu od 0 do 255. Vyšší číslo zpravidla znamená jasnější obraz.
Nastavení kontrastu můžeme provést po spuštění displeje:
displej.begin(); //spusť OLED displej
displej.setContrast(100); //nastav nižší kontrast
Nejnižší hodnota nemusí znamenat úplně zhasnutý displej. Konkrétní výsledek se může mírně lišit podle použitého panelu.
Při použití v místnosti většinou není potřeba nastavovat maximální jas. Nižší kontrast může být příjemnější na pohled a zároveň omezí zatěžování OLED pixelů.
Vypnutí displeje
Pokud zařízení displej delší dobu nepotřebuje, můžeme ho softwarově vypnout:
displej.setPowerSave(1); //vypni displej
Opětovné zapnutí provedeme příkazem:
displej.setPowerSave(0); //zapni displej
Obsah obrazové paměti Arduina tím není automaticky vymazaný. Po zapnutí se proto může znovu objevit předchozí obraz.
Tato funkce se hodí například u zařízení napájených z akumulátoru nebo u displeje, který se má rozsvítit pouze po stisknutí tlačítka.
Spotřeba OLED displeje
Spotřeba OLED displeje závisí také na tom, kolik pixelů právě svítí. Obrazovka s několika malými znaky proto obvykle odebírá méně než plocha vyplněná velkým bílým obdélníkem.
Při bateriovém napájení je proto výhodné:
- Používat pouze potřebné množství svítících pixelů
- Nenastavovat zbytečně vysoký kontrast
- Displej při nečinnosti vypnout
- Nezobrazovat velké vyplněné bílé plochy
Samotné snížení rychlosti překreslování nemusí výrazně snížit spotřebu OLED panelu. Rozsvícené pixely totiž odebírají proud i v době, kdy obraz právě neměníme.
Dlouhodobé zobrazování stejného obrazu
Jednotlivé OLED pixely se během provozu postupně opotřebovávají. Pokud bude displej dlouhodobě zobrazovat stále stejný obsah, mohou se nejčastěji používané pixely opotřebovat rychleji než okolní plocha.
Po delší době se pak může objevit nerovnoměrný jas nebo slabě viditelný zbytek původního obrazu.
U běžných domácích projektů se tento problém nemusí projevit rychle. Přesto je vhodné hlavně u zařízení pracujících nepřetržitě dodržet několik jednoduchých pravidel:
- Vypínat displej, když není potřeba
- Nepoužívat zbytečně maximální kontrast
- Občas změnit polohu statických údajů
- Vyhnout se dlouhodobému zobrazení velkých bílých ploch
- Použít automatické zhasnutí po určité době
OLED je proto výborný pro zařízení, na kterém se hodnoty průběžně mění nebo které se zapíná pouze při používání. Pro nepřetržité zobrazování stejného obrazu po mnoho měsíců mohou být vhodnější jiné zobrazovací technologie.
Výhody a omezení malého displeje
Hlavní výhodou tohoto modulu jsou jeho malé rozměry. Displej se vejde i do drobné krabičky a díky komunikaci I²C nezabere mnoho vývodů mikrokontroléru.
Mezi jeho výhody patří:
- Malé rozměry
- Dobře čitelný obraz
- Vysoký kontrast
- Jednoduché připojení pomocí I²C
- Napájení 3,3 až 5 V
- Možnost zobrazovat text i grafiku
- Rozšířený řadič SSD1306
- Velký výběr hotových knihoven
Největším omezením je výška pouhých 32 pixelů. Na displej se nevejde velké množství informací a při návrhu obrazovky je potřeba dobře využít dostupné místo.
Mezi omezení patří:
- Malá zobrazovací plocha
- Omezený počet řádků textu
- Pouze jedna barva pixelů
- Postupné opotřebovávání OLED panelu
- Vyšší spotřeba při velkém počtu rozsvícených pixelů
- Horší vhodnost pro dlouhodobě neměnný obraz
Displej se nejlépe uplatní tam, kde potřebujeme zobrazit jednu nebo několik důležitých hodnot a zároveň chceme zachovat malé rozměry celého zařízení.
Závěr
Malý OLED displej s rozlišením 128 × 32 pixelů sice nenabízí mnoho prostoru, ale při rozumném návrhu obrazovky dokáže přehledně zobrazit hlavní hodnotu, krátký stav, jednoduchou ikonu nebo několik položek menu. Díky komunikaci přes I²C navíc zabere pouze dva komunikační piny a snadno se přidá i k zařízení s dalšími moduly.
Knihovna U8g2 umožňuje kromě textu kreslit také základní grafiku, bitmapy a jednoduché animace. Při dlouhodobém provozu je jen potřeba počítat se spotřebou svítících pixelů a nenechávat zbytečně dlouho zobrazený stejný obraz při maximálním jasu. Pro malé měřáky, stavové panely a kompaktní zařízení je ale tento displej velmi dobře použitelný.
Různé druhy OLED displejů zakoupíte na Laskakit.cz, přímý odkaz je ZDE.
Další díly ze začátečnické série o modulech najdete ZDE.
