SPI (I²C) OLED displej SSD1306 v MicroPythonu
V dnešním článku si ukážeme, jak v MicroPythonu připojit k modulu ESP32 OLED displej s řadičem SSD1306. OLED displej je poměrně vděčnou a efektní periférií, takže návodů na jeho připojení a použití se dá na internetu najít mnoho. Obvykle se jedná o návody pro displej se sběrnicí I²C, který je v tomto případě jistě dobrou volbou. My se tedy pokusíme být aspoň trochu originální a zaměříme se na připojení OLED displeje přes sběrnici SPI. I když, jak uvidíme, tak si vlastně ukážeme i to, jak v MicroPythonu řídit displej se sběrnicí I²C.
Upřímně řečeno… motivace, proč se dnes vrhneme na OLED displej se sběrnicí SPI, není jen chuť být originální oproti ostatním článkům, ale je ještě jedna. Na trhu se objevuje „obojetný“ OLED displeje, který nabízí použití jak s I²C, tak se SPI sběrnicí. To pochopitelně zní lákavě! Tak se pojďme podívat, co si to pak ve svém oblíbeném elektro e-shopu vlastně pořídíme.
I²C nebo SPI?
Než se pustíme samotného OLED displeje nabízejícího použití sběrnic I²C a SPI, zkusíme obě sběrnice alespoň trochu představit a porovnat.
I²C (Inter-Integrated Circuit)
Sériová sběrnice navržená pro komunikaci mezi čipy na krátké vzdálenosti. Vytvořena firmou Philips (dnes NXP). Funguje na principu adresování zařízení, tedy každé zařízení má svou jedinečnou adresu. Všechna zařízení jsou připojena na stejné dvě linky, jedna je datová, druhá hodinový signál. Jak bylo naznačeno, může být více slave zařízení (např. senzory, displeje, EEPROM) na jedné sběrnici. Komunikace je řízena masterem (např. mikrokontrolér). Napěťová komunikace může být na úrovni dané napájecím napětím, v našem „bastlířském“ světě to znamená zpravidla 3,3 V nebo 5 V.
- SDA – datová linka
- SCL – hodinová linka
- Jednoduché zapojení (pouze 2 vodiče i pro více zařízení).
- Šetří piny na mikrokontroléru.
- Skvělé pro pomalejší přenosy (např. čtení teploty, posílání textu).
- Nižší přenosová rychlost.
- Náchylnější na rušení (citlivé na delší vodiče).
- Při větším počtu zařízení může být komunikace pomalejší.
SPI (Serial Peripheral Interface)
Rychlá sériová sběrnice vyvinutá firmou Motorola. Používá se pro připojení zařízení, kde je důležitá rychlost přenosu dat. Přímá komunikace mezi řadičem (master) a jednotlivými periferními zařízeními (slave). Komunikace na sběrnici probíhá v režimu „full-duplex“, tedy data mohou proudit oběma směry zároveň – a to nezávisle na sobě – je zde linka jak pro směr tam (MOSI
), tak zpět (MISO
). Sběrnice zpravidla využívá 4 vodiče pro obousměrnou komunikaci nebo jen tři pro komunikaci jedním směrem. Součástí sběrnice je signál CS
pro výběr dané periférie. Na jedné sběrnici může být připojeno několik periférií, periférie jsou „adresovány“ pomocí pinu CS
, kterým je pro danou periférii určeno, zda aktuální komunikace je pro ni platná. Z hlediska elektrické podoby i zde se většinou setkáváme s normou 3,3 V nebo 5 V.
- MOSI – Master Out Slave In (komunikace z řadiče)
- MISO – Master In Slave Out (komunikace do řadiče)
- SCK – hodinová linka
- CS/SS – Chip Select/Slave Select (výběr periférie)
- Vysoká přenosová rychlost (až desítky MHz)
- Stabilnější a spolehlivější na kratší i střední vzdálenosti.
- Ideální pro rychlá zařízení (displeje, paměti, ADC/DAC).
- Vyžaduje více vodičů – pro každé zařízení zvlášť
CS
(chip select) signál. - Méně vhodné pro připojení většího množství zařízení.
- Nemá žádné adresování – každé zařízení potřebuje vlastní výběrový signál
CS
.
Tabulka srovnání:
I²C | SPI | |
---|---|---|
Počet vodičů | 2 (SDA – data, SCL – hodiny) | 4 (MISO, MOSI, SCLK, CS) |
Rychlost | Nižší (typ. do 400 kHz, high-speed až 3,4 MHz) | Vyšší (typ. až 10+ MHz) |
Topologie | Více zařízení na jedné sběrnici (adresace) | Obvykle 1:1, nebo více zapínané přes různé CS piny |
Komunikace | Half-duplex (data vždy jen v jednom směru najednou) | Full-duplex (možnost současné obousměrné komunikace) |
Složitost kódu | Jednodušší, vestavěná podpora v knihovnách | O něco složitější na řízení více zařízení |
Potřeba pinů | Méně (sdílí dvě linky pro všechna zařízení) | Více (každé zařízení potřebuje vlastní CS pin) |
OLED displej SPI/I²C
Současný trh s elektronickými součástkami je doslova zaplaven různými nepřebernými komponentami. Nejinak je tomu v oblasti OLED displejů. Co si budeme říkat, někteří prodejci dle nejnižší ceny berou své zboží od různých dodavatelů a někdy si ani nevšimnou, že již prodávají trochu něco jiného, než mají v popisu a na fotografiích svého e-shopu. Nákup v oblasti elektroniky tedy občas trochu připomíná loterii. Také by občas neškodilo, kdyby v daném e-shopu byl k dispozici návod nebo datový list. O nějaké ukázkové aplikaci ani nemluvě! Není tedy nic překvapivého, že až po nákupu zjistíme, že „přepnutí“ displeje z SPI na I²C není jen záležitostí nějakého přepnutí jumperu, ale vyžaduje to pájení SMD součástek. Koupíte-li OLED displej slibující možnost komunikace pod oběma systémy (I²C a SPI), vězte tedy, že se bez páječky a pinzety neobejdete! V případě běžně prodávaných těchto „obojetných“ displejů změna systému komunikace vyžaduje přepájení minimálně jednoho (nebo více) SMD rezistorů!
I když by vše mělo být bezproblematické, moc tuto cestu nedoporučujeme, a to zejména začínajícím elektro nadšencům. Na internetu lze na několika fórech najít příspěvky, kde se různí bastlíři potýkají s různými displeji. Někdy opravdu stačí jen přepájet jeden rezistor, jindy je těch rezistorů více, občas ještě sem tam nějaký ten zkratovací drátek. A pak ještě nastavit piny jako jsou CS a RST na správné úrovně, tu je to LOW, tamhle zase HIGH…
Někdy je to už opravdová divočina! Jestli nákup někdy připomíná loterii, tak toto je už spíše na úrovni dobrodružné skautské výpravy. 😊
Naše doporučení je tedy opravdu si dopředu zvolit typ sběrnice a podle toho pak displej koupit pro tu jednu určenou. Při nákupu těchto obojetných displejů je určitě také dobré ověřit si (jak asi?!), jaká sběrnice je vlastně tou výchozí nastavenou od výrobce. Jasno do toho ani nevnáší popis pinů displejů. Podívejme se na následující obrázky, které ukazují jednotlivé displeje (a nejsou to pochopitelně všechny!), na které můžeme v e-shopech s elektronikou narazit.

I²C displej (4 piny)
Tam, kde se nemůžeme zmýlit, je klasický I²C OLED displej se 4 piny. Kromě dvojice napájení VCC
a GND
jsou zde dva signálové vodiče SCL
a SDA
. Dokonce i popisky SCL
a SDA
odpovídají standardu dané sběrnice.
Takový displej lze připojit pouze sběrnicí I²C a není co řešit!

SPI displej s popisem I²C (6 pinů)
Prvním „exotem“ z oblasti obojetných displejů je displej, který většinou primárně bývá zapojen pro sběrnici SPI, ale potiskem spíše odpovídá sběrnici I²C. Piny napájení jsou jasné, popisy pinů sběrnice SPI ale spíše odpovídají popisům sběrnice I²C! Zapojení SPI tedy bude následovné:
- SCL – Serial Clock Line (v I²C komunikaci je to hodinová linka), ale v SPI to odpovídá hodinové lince SCK
- SDA – Serial Data Line (v I²C je to datová linka), ale v SPI to odpovídá MOSI (Master Out Slave In)
- RES – resetovací pin (není součástí ani SPI, ani I²C datového přenosu), je třeba nastavit na správnou úroveň nebo použít knihovnu, která s tímto pinem umí pracovat
- DC – Data/Command (v SPI jde o pin, který určuje, zda jsou data interpretována jako příkaz nebo jako data pro displej). Tento pin je specifický pro OLED displeje.
Datová linka MISO (Master In Slave Out) zde není potřeba, tak není použita

SPI displej s D0, D1 a CS (7 pinů)
Tento displej svým popis neodpovídá ani SPI, ani I²C. Navíc nám u tohoto OLED displeje přibyl ještě jeden pin. (piny napájení v přehledu neuvádíme)
- D0 – pin odpovídá SCK (Serial Clock) v SPI (při přepájení na I²C asi SCL)
- D1 – pin odpovídá MOSI (Master Out Slave In) v SPI (u I²C asi SDA)
- RES – resetovací pin (viz dříve)
- DC – Data/Command pin (viz dříve)
- CS – Chip Select (pin sběrnice SPI, který určuje, zda konkrétní zařízení na sběrnici má být aktivní)
Sedmipinový displej bychom měli použít (díky přítomnosti pinu CS
), pokud potřebujeme k SPI sběrnici připojit několik SPI periférií zároveň.
Fajn, koupili jsme si displej, který je ve výchozím stavu určen pro SPI sběrnici. Přepajovat ho na I²C nechceme, tak co teď s ním? Přece ho nevyhodíme! Tak se pojďme podívat, jak tento displej připojit k modulu ESP32 s MicroPythonem.
Budeme tedy nadále používat některý ze SPI displejů se 6 nebo 7 piny.
Připojení SPI displeje SSD1306 k modulu ESP32
ESP32 disponuje čtyřmi hardwarovými SPI řadiči pro periferie, jsou to: SPI0
, SPI1
, SPI2
(označováno jako HSPI
) a SPI3
(označováno jako VSPI
). Sběrnice SPI0
a SPI1
se používají v modulu ESP32 interně, například ke komunikaci s vestavěnou pamětí flash, a neměli bychom je používat pro jiné úkoly. Zbývají nám tedy sběrnice HSPI
(SPI2
) a VSPI
(SPI3
).
- Poznámka:
- Aby situace kolem označování SPI nebyla (asi) příliš jednoduchá, tak MicroPython pro modul ESP32 označuje tyto sběrnice jinými čísly! Musíme si tedy zapamatovat, že
SPI2
(aliasHSPI
) je v MicroPythonu dostupná pod označenímSPI(1)
aSPI3
(VSPI
) najdeme pod označenímSPI(2)
.
Pro komunikaci s perifériemi musíme tedy používat jen dostupné sběrnice SPI. Budeme je nadále pojmenovávat HSPI
a VSPI
a na nějaká čísla sběrnic si maximálně vzpomeneme až při zápisu kódu programu.
Většina desek ESP32 má pevně přiřazené výchozí piny hardwarových sběrnic SPI. Je tam sice určitá možnost volby, ale teď v tom nebudeme dělat zmatky! Pro začátek tedy budeme muset při připojení displeje dodržet jasně dané piny a jejich role (viz následující tabulka).
Mapování pinů SPI sběrnice pro většinu desek ESP32:
SPI | MOSI | MISO | SCK | CS |
---|---|---|---|---|
HSPI | GPIO 13 | GPIO 12 | GPIO 14 | GPIO 15 |
VSPI | GPIO 23 | GPIO 19 | GPIO 18 | GPIO 5 |
Trochu asi předbíháme, ale neodpustíme si informaci, že pokud bychom opravdu chtěli připojit SPI periférii k „libovolným“ pinům modulu ESP32, uvidíme dále, že hardwarové SPI není jedinou možností!
Pro připojení SPI displeje SSD1306 využijeme VSPI
(v MicroPythonu označeném jako SPI(2)
). Propojení pinů OLED displeje a modulu ESP32 znázorňuje následující obrázek. Na schématu máme použit 7 pinový displej, ale pokud použijeme 6 pinový displej, jen vynecháme propojení z pinu GPIO5
. Pokud nás zarazilo, že jsme dle tabulky výše nepoužili GPIO19
, který na sběrnici SPI umožňuje komunikaci od periférie do modulu ESP32, jistě nás napadne, že signál MISO
na displeji asi není potřeba (zde displej nemá co hlásit).

Zatímco propojení SPI linky a pinu SCK
(GPIO18
), MOSI
(GPIO23
) a CS
(GPIO5
) je zde nutné dodržet, tak linky (piny) RES
(GPIO16
) a DC
(GPIO17
) si můžeme zvolit. Aktuálně zvolená konfigurace sběrnice VSPI
a propojení modulu ESP32 s displejem je shrnuto v následující tabulce.
Modul ESP32 – VSPI | OLED SSD1306 – SPI |
---|---|
GND | GND |
3V3 | Vcc |
GPIO18 | SCK (SCL) |
GPIO23 | MOSI (SDA) |
GPIO16 | RES |
GPIO17 | DC |
GPIO5 | CS |
GPIO19 (nepoužito) | --- |
Řízení displeje SSD1306 přes sběrnici SPI MicroPythonem na modulu ESP32
Řízení OLED displeje s řadičem SSD1306 už asi není tak jednoduché, abychom jej řešili přímým přístupem na jednotlivé piny, využijeme tedy obslužnou knihovnu. Knihovna se jmenuje ssd1306
a můžeme ji najít na internetu.
Zde ale nastává první problém!
Na internetu lze nalézt hned několik knihoven stejného jména. Některé jsou určitými klony základní knihovny, jiné jsou samostatnými výtvory svých autorů. Některé jsou obecně pro micropython, jiné pro konkrétní modul např. ESP32, Raspberry… Všechny slibují totéž – ovládat OLED displej SSD1306. Ale ne se všemi nám program bude na modulu ESP32 fungovat. A to dokonce i při použití ukázkových pythonovských kódů uvedených u dané verze knihovny! To je velmi zvláštní… 😕
Uvedeme si zde tedy postup, jak získat knihovnu, se kterou nám ovládání OLED displeje funguje. I když, jak uvidíme, ta funkčnost bez zádrhele nebude!
Instalace knihovny ssd1306
Naštěstí prostředí Thonny disponuje správcem „balíků“ (což jsme už poznali v některém z předešlých článků), pomocí kterého stáhneme knihovnu určenou přímo pro náš modul. Ostatní knihovny, které lze na internetu najít a které občas slibují i větší paletu příkazů, zatím necháme pro odvážnější bastlíře.
Načtení knihovny ssd1306 v prostředí Thonny
I když jsme si zde postup instalace knihovnu pomocí prostředí Thonny ukazovali, myslím, že nyní připomenutí postupu nebude na škodu.
- Připojíme k USB portu počítače s nainstalovaným prostředím Thonny modul ESP32 s firmwarem MicroPythonu, do kterého budeme chtít nainstalovat kód modulu
ssd1306
. - V prostředí Thonny v menu Nástroje vybereme volbu Spravovat balíky.
- Do vyhledávacího pole okna správce „balíků“ zadáme klíčové slovo ssd1306 a vybereme nabízený balík, který je modulem pro ovládání OLED displeje.
- Instalaci spustíme kliknutím na tlačítko Instalace. Do připojeného modulu ESP32 se začne z internetu stahovat kód modulu (knihovny)
ssd1306
– viz následující obrázek.

Jakmile máme modul ssd1306
stažený do modulu ESP32, můžeme se pustit do programování. Jen si připomeňme, že se modul ssd1306
stáhl do připojeného zařízení (modulu ESP32), nikoliv do prostředí Thonny. Připojíme-li jiný modulu ESP32, musíme do něj knihovnu opět nainstalovat (postup opakovat).
Knihovna ssd1306
Knihovna ssd1306
slouží pro ovládání OLED displejů s řadičem ssd1036
a je vytvořena tak, aby fungovala pro displeje připojené jak sběrnicí SPI, tak I²C. Její použití je tedy univerzální! Pokud budeme připojovat OLED displej se sběrnicí I²C, zvolíme úplně stejný postup i knihovnu. Dále si tedy zkusíme ukázat, jak knihovnu nakonfigurovat pro sběrnici SPI i I²C. I když pak budeme pokračovat jen na sběrnici SPI!
Hardwarové SPI v modulu ESP32:
Jak jsme uvedli, modul ESP32 má v MicroPythonu dostupné dvě sběrnice SPI (HSPI
a VSPI
). Pro ovládání SPI periférií musíme využít piny, které jsou k jednotlivým SPI řadičům připojené (viz dřívější tabulka)! Pro ovládání hardwarového SPI se používá objekt SPI
, který je součástí modulu machine
.
Následující ukázka kódu ilustruje, jak lze nastavit komunikaci s OLED displejem SSD1306 pomocí VSPI
.
from machine import Pin, SPI
import ssd1306
# hspi = SPI(1) # sck=14 (scl), mosi=13 (sda), miso=12 (unused)
vspi = SPI(2) # sck=18 (scl), mosi=23 (sda), miso=19 (unused)
dc = Pin(17) # data/command
rst = Pin(16) # reset
cs = Pin(5) # chip select, some modules do not have a pin for this
# display = ssd1306.SSD1306_SPI(128, 64, hspi, dc, rst, cs)
display = ssd1306.SSD1306_SPI(128, 64, vspi, dc, rst, cs)
Pro nás je zde především důležitá deklarace objektu display
, který nám umožní ovládat připojený OLED displej. Metodou SSD1306_SPI
určujeme komunikační sběrnici SPI a nastavujeme zde následující parametry (po řadě): rozlišení v x-ovém směru (zde 128), rozlišení v y-ovém směru (64), objekt komunikační sběrnice (vspi
), pin data/command (cd
), pin reset (rst
) a pin chip select (cs
). Piny jako je SCK
, MOSI
, MISO
jsou deklarovány v rámci defaultního nastavení zvoleného řadiče SPI(2)
. Ostatní piny jsou zadány pomocí proměnných dc
, rst
a cs
.
V ukázce je zakomentována i možnost zvolení HSPI
, tj. SPI(1)
. V tom případě je třeba v metodě SSD1306_SPI
zvolit za typ komunikační sběrnice proměnnou hspi
a odkomentovat
potřebnou deklaraci hspi
.
Softwarové SPI v modulu ESP32:
Když jsme se zmiňovali, že modul ESP32 umožňuje nastavit sběrnici SPI na „jakémkoliv“ pinu, tak jsme měli na mysli možnost tzv. softwarového SPI. V tom případě není využíván hardwarový řadič, ale je ovládání SPI sběrnice simulováno softwarově vnitřním programem. Toto řešení je takovým plánem B, pokud bychom již obsadili obě SPI sběrnice, nebo je nemohli využít z jiného důvodu. Pochopitelně softwarové řešení SPI komunikace má určité omezení, kupříkladu více zatěžuje procesor. To nás ale při našem jednoduchém projektu moc tížit nebude. Výhodou tohoto řešení je, že ho lze realizovat téměř na jakékoliv sadě pinů (pokud to pochopitelně samotný charakter pinu dovolí).
Pro používání softwarového SPI využijeme objekt SoftSPI
, který je také součástí modulu machine
. Na rozdíl od hardwarového SPI, kde jsou defaultně nastaveny výchozí piny a i určitý standard komunikace, zde musíme alespoň některá tyto parametry nastavit ručně. Jedná o následující parametry (některé naštěstí mají výchozí hodnoty, tak dále v kódu nejsou nastavovány):
baudrate
– hodinová frekvence na pinuSCK
.polarity
– může být 0, nebo 1 a je to úroveň, na které se nachází nečinná hodinová linka.phase
– může být 0, nebo 1, aby se data vzorkovala na první, resp. druhé hraně hodin.bits
– je šířka každého přenosu v bitech.firstbit
– určuje pořadí zasílaných bitů z odesílaného bytu (může býtSPI.MSB
, neboSPI.LSB
)sck
,mosi
,miso
jsou objekty pinů, které se použijí pro jednotlivé signály sběrnice.
from machine import Pin, SoftSPI
import ssd1306
spi = SoftSPI(baudrate=500000, polarity=1, phase=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
dc = Pin(17) # data/command
rst = Pin(16) # reset
cs = Pin(5) # chip select, some modules do not have a pin for this
display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
Jakmile máme vytvořený objekt spi
, který odpovídá objektu sběrnice SPI, je další použití úplně stejné, jako v případě hardwarového SPI. Objekt SPI sběrnice dosadíme jako určený parametr do metody SSD1306_SPI
. Z hlediska programu je pak již jedno, zda se jedná o SPI hardwarové nebo softwarové, tyto záležitosti jsou plně v režii modulu ESP32.
I²C interface:
Když už jsme slíbili i ukázku pro použití I²C displeje, připojujeme tedy následující ukázku kódu pro sběrnici I²C:
from machine import Pin I2C
import ssd1306
# using default address 0x3C
i2c = I2C(sda=Pin(4), scl=Pin(5))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
Vidíme, že základním komunikačním objektem pro I²C sběrnici bude objekt I2C
, který importujeme z modulu machine
. Knihovně ssd1306
pak potřebné informace předáme pomocí metody SSD1306_I2C
, jejíž parametry jsou opět rozměry (rozlišení) použitého OLED zobrazovače a pochopitelně objekt komunikační sběrnice. V konfiguraci objektu pro I2C
sběrnici vidíme, že byly zvoleny komunikační piny GPIO4
a GPIO5
, kde zvolené parametry určují roli (SDA
/SCL
) těchto pinů. Tím máme vyřízenou komunikaci s displejem. Další práce s displejem je na úrovni knihovny ssd1306
a ta je na použiré sběrnici nezávislá. Výše uvedené nastavení je tedy vše, co by nám mělo pro komunikaci I²C stačit, vše ostatní bude stejné jako při kominikaci přes SPI.
Práce s OLED displejem
Jakmile má MicroPython definovaný objekt display
(ať již na jakékoliv sběrnici), otevírá se nám paleta metod, které nám umožní zapisovat do vyrovnávací paměti displeje, a pak tyto data jednorázově zobrazit. To je třeba si uvědomit! Samotné provedení nějakého příkazu neovládá rovnou zobrazovací OLED jednotku, ale vytváří určitý datový obraz ve vyrovnávací paměti. Až metoda show()
způsobí zobrazení!
Než se pustíme do ukázkového programu, podíváme se na základní metody modulu ssd1306
:
show()
– prokopíruje zadaná data zobrazení z vyrovnávací paměti na displej (je třeba volat vždy, pokud chceme, aby se nějaký příkaz projevil na OLED displeji)invert(False/True)
– zapíná/vypíná displeji inverzní režim (co bylo tmavé, svítí a naopak). Důležité je vědět, dvě věci:- Co bylo na displeji namalováno, je okamžitě přemalováno inverzně (není třeba to tedy malovat znova nebo volat metodu show)
- Parametr určující barvu pixelů při inverzním režimu funguje obdobně jako při režimu normálním, tedy co má být vidět bude vidět (bude zhaslé na svítícím pozadí) a co má mít barvu pozadí, nebude vidět (svítí na svíticím pozadí)
rotate(False/True)
– svisle převrací zobrazení na displeji. Používá se, pokud díky umístění displeje potřebujeme zobrazovat vzhůru nohama (obraz je převrácen tak, aby byl čitelný, ne jen vertikálně)contrast(0–255)
– nastavuje úroveň svitu OLED pixelů, podle dokumentace vstupní parametr umožňuje rozmezí hodnot 0–256, ale zkušenost ukazuje, že reálně použitelné hodnoty jsou asi jen 0 (málo), 64 (trochu) a 255 (maximum).poweron()
– zapnutí zobrazování displeje (po zapnutí napájení displeje není třeba tuto metodu používat pro nějaké „zapnutí“ zobrazování), spíše slouží jako rozsvícení po dočasném zhasnutí displeje.poweroff()
– vypnutí zobrazování displeje (dočasné zhasnutí displeje)text(text, X, Y, col)
– vypíše obsah řetězecetext
na souřadniceX
(šířka) aY
(výška) barvoucol
– u monochromatického displeje barva 0 znamená barvu pozadí a 1 viditelnou barvy (i při inverzním režimu)pixel(X, Y, col)
– vykreslí se bod na souřadnicíchX
,Y
barvoucol
line(X1, Y1, X2, Y2, col)
– zobrazí se úsečka mezi souřadnicemiX1
,Y1
aX2
,Y2
barvoucol
fill(col)
– vyplní displej zvolenou barvoucol
(1 znamená viditelnost, 0 barvu pozadí)hline(X, Y, del, col)
– vodorovná čára ze souřadnicX
,Y
o délcedel
(počet pixelů) a barvěcol
vline(X, Y, del, col)
– svislá čára ze souřadnicX
,Y
o délcedel
(počet pixelů) a barvěcol
rect(X, Y, dX, dY, col)
– vykreslí hranice obdélníku s levým horním rohemX
,Y
, délkami strandX
,dY
a barvoucol
fill_rect(X1, Y1, dX, dY, col)
– zobrazí výplň obdélníku (parametry jako urect
) barvoucol
poly(X,Y, pole, col)
– vykreslí lomenou čáru dle souřadnic v polipole
na místo s levým horním rohem na souřadnicíchX
,Y
barvoucol
– souřadnice lomené čáry jsou absolutní vzhledem k levému hornímu rohu, tzn. žádné záporné hodnoty (relativně vztažené k počátku!)scroll(SX, SY)
– posune obraz celého displeje ve směruSX
,SY
(kladné hodnoty znamenají vpravo/dolů, záporné vlevo/nahoru). Na původním místě odkud bylo něco odsunuto, ale nic tam nebylo přisunuto, zůstane část původního motivu.
Jak bylo naznačeno, lze na internetu najít i knihovny, které zvládají další příkazy, například příkaz pro elipsu a podobně. Ale osobní zkušenost s funkčností takových knihoven není nic moc.
Následující kód programu představuje ukázkový program, který by měl ukázat některé z výše uvedených metod. Předem upozorňujeme, že i když je zde propojení OLED displeje a modulu ESP32 takové, že odpovídá použití hardwarového VSPI
, nakonec komunikaci řídíme pomocí softwarového SoftSPI. (důvody viz dále)
Kód programu:
from machine import Pin, SoftSPI
import ssd1306
import array
import time
# SPI(1) - sck=14 (scl), mosi=13 (sda), miso=12 (unused)
# SPI(2) - sck=18 (scl), mosi=23 (sda), miso=19 (unused)
spi = SoftSPI(baudrate=500000,
polarity=1,
phase=0,
sck=Pin(18), mosi=Pin(23), miso=Pin(19) # piny pro SPI(2)
)
dc = Pin(17) # data/command
rst = Pin(16) # reset
cs = Pin(5) # chip select
display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
blik = Pin(2, Pin.OUT)
display.poweron()
display.contrast(255)
display.rotate(False)
display.invert(0)
display.fill(0)
display.text('FyzKAB 4ever!', 15, 1, 1)
display.text('FK', 57, 35, 1)
display.line(0, 10, 127, 10, 1)
display.rect(0, 0, 128, 64, 1)
display.show()
def efekt(barva):
uhelnik = array.array('I', [0, 0, 80, 0, 80, 50, 0, 50, 0, 0])
krokX = 8
krokY = 5
display.invert(not(barva))
for i in range(0, 10):
# zmena hodnot na indexech 0, 3, 8 o kroky
display.poly(24,13, uhelnik, barva)
display.show()
uhelnik[0] += krokX
uhelnik[3] += krokY
uhelnik[4] -= krokX
uhelnik[7] -= krokY
uhelnik[8] += krokX
time.sleep(0.2)
while True:
blik.off()
efekt(1)
time.sleep(1)
blik.on()
efekt(0)
time.sleep(1)
Kód programu je již trochu delší, stejně tak i seznam importovaných modulů (knihoven). Ale kromě použití polí, které si dále vysvětlíme, zde není nic, co bychom již v našem dosavadním „článkovém maratonu“ nepotkali.
První část, kde nastavujeme komunikační sběrnici, knihovnu ssd1306
a ostatní komunikačními piny jsme si již ukázali. V kódu se tedy můžeme přesunout až k deklaraci proměnné blik
. Tato proměnná je objektem pro ovládání pinu GPIO2
, na kterém je na našem vývojovém kitu modulu ESP32 připojena vestavěná LED. Tu budeme čistě jen pro efekt rozsvěcet při přepnutí displeje do inverzního režimu. To nám může posloužit jako takový ukazatel běhu programu, pokud by se na OLED displeji nic nezobrazovalo.
Následují úvodní nastavení displeje, jako je zapnutí poweron()
(není třeba), nastavení kontrastu na maximum contrast(255)
, volba orientace rotate(False)
a nastavení stavu inverze invert(0)
(zde si všimněte, že místo deklarované hodnoty False
/True
používéme možnost použití hodnoty 0
a 1
). Většina těchto nastavení je na začátku programu zbytečná a je zde v kódu uvedena jen proto, aby si s nimi mohli případní zájemci hrát.
display.poweron()
display.contrast(255)
display.rotate(False)
display.invert(0)
Následuje smazání displeje fill(0)
a výpis textů, čáry a orámování obdélníkem:
display.fill(0)
display.text('FyzKAB 4ever!', 15, 1, 1)
display.text('FK', 57, 35, 1)
display.line(0, 10, 127, 10, 1)
display.rect(0, 0, 128, 64, 1)
Na displej se však zatím nic nezobrazí, to se provede až po provedení příkazu show()
:
display.show()
Následuje definice funkce efekt()
, která slouží pro vykreslení efektu, který si pamětníci pamatují z televizního pořadu Vega. Jde o postupné vykreslování vepsaného čtyřúhelníku do obdélníku. Čtyřúhelník vykreslujeme pomocí metody poly()
, abychom viděli, jak se vykresluje lomená čára.
Ve funkci efekt()
je i nastavení inverzního zobrazení a barvy vykreslování tak, aby při první průběhu se obrazec vykreslil a při druhém smazal. S těmito různými parametry je funkce volána v hlavní nekonečné smyčce.
Práce s polem v MicroPythonu
Z hlediska našeho studia (Micro)Pythonu je nyní spíše zajímavější použití pole, než samotný grafický efekt na OLED displeji. Pojďme se tedy na chvíli podívat, jak se s polem v (Micro)Pythonu pracuje.
V (Micro)Pythonu se můžeme setkat s několika způsoby práce s poli (nebo poli podobnými strukturami). V některých případech je třeba importovat modul array
, zatímco jindy můžeme používat standardní seznamy (lists), jako v jiných programovacích jazycích.
Seznamy jsou v Pythonu velmi flexibilní a uživatelsky přívětivé. Můžeme do nich ukládat různé typy dat (čísla, řetězce, objekty apod.), a je to nejběžnější způsob práce s „poli“ v běžném Pythonu.
Např.:
seznam = [1, 2, 3, 4]
seznam.append(5)
print(seznam) # Výstup: [1, 2, 3, 4, 5]
V MicroPythonu je situace trochu jiná, protože to je odlehčená verze Pythonu určená pro malé zařízení a mikrokontroléry (např. ESP32). V některých případech je tedy v MicroPythonu nutné používat modul array
, aby se efektivněji spravovala paměť, protože běh na těchto zařízeních bývá omezený. Pokud tedy pracujeme s polem v MicroPythonu a potřebujeme optimalizovat využití paměti nebo rychlost, pomůže nám modul array
. Na druhou stranu, pokud nepotřebujeme takovou optimalizaci a jednoduše potřebujeme seznamy, můžeme použít standardní seznamy.
Modul array
se používá, jak jsme řekli, pro efektivní práci s polem, které obsahuje hodnoty stejného typu. Je to typické pro aplikace, kde potřebujeme vysoký výkon nebo chceme mít pole, které bude mít nižší paměťovou náročnost než seznamy.
import array
# Vytvoření pole celých čísel (typ 'i' znamená integer)
pole = array.array('i', [1, 2, 3, 4])
pole.append(5)
print(pole) # Výstup: array('i', [1, 2, 3, 4, 5])
Pole v modulu array
jsou v Pythonu tzv. typová, což znamená, že když deklarujeme pole, určíme jeho typ (například pouze celé číslo, pouze desetinné číslo apod.).
Deklarace takového pole pak vypadá následovně, například v našem kódu:
uhelnik = array.array('I', [0, 0, 80, 0, 80, 50, 0, 50, 0, 0])
Metoda array
objektu array
má v tomto případě dva argumenty. První parametr je typ pole (zadáno klíčovým znakem, zde 'I'
), druhým parametrem je uspořádaná n-tice jednotlivých prvků pole (zde postupně x-ové a y-ové souřadnice lomené čáry).
Klíčový znak, který udává typ pole, může být následující (viz tabulka):
znak | typ | počet bytů | Poznámka |
---|---|---|---|
b | signed char | 1 | -127 až 127 |
B | unsigned char | 1 | 0 až 255 |
h | signed short | 2 | -32 768 až 32 768 |
H | unsigned short | 2 | 0 až 65 535 |
i l |
signed int signed long |
4 | -2 147 483 648 až 2 147 483 647 |
I L |
unsigned int unsigned long |
4 | 0 až 4 294 967 295 |
q | signed long long | 8 | -9 223 372 036 854 775 807 až 9 223 372 036 854 775 807 |
Q | unsigned long long | 8 | 0 až 18 446 744 073 709 551 615 |
f | float | 4 | reálné číslo (Pokud je podporováno) |
d | double | 8 | |
u | Unicode character | 2 | speciálně pro ukládání znaků |
- Ještě k tomu připomeňme:
- Pole nemusíme zadávat jen výčtem konkrétních prvků, ale můžeme také pole inicializovat s počátečními hodnotami, které jsou výchozí.
Např. pole o 10 prvcích s výchozí hodnotou 0:
pole = array.array('B', [0] * 10)
Pole lze zadat i jako prázdné a pak prvky přidávat:
pole = array.array('B')
for _ in range(10):
pole.append(0) # nebo nějaké jiné výchozí hodnoty
To je k rychlému seznámení s polem a modulem array
zatím asi vše.
Vraťme se k našemu OLED displeji!
Spustíme kód a měli bychom na displeji získat jednoduchý grafický efekt. Zvídavý čtenář si určitě zkusí zaexperimentovat se změnou různých parametrů a efektů.

Problém s hardwarovým SPI
Jestliže vše funguje, můžeme se konečně podívat na problém, který jsme zde již dříve tak trochu avizovali. Zároveň tím vysvětlíme, proč výše uvedený program využívá SoftSPI, nikoliv hardwarové SPI.
Problém je, i když je jak zapojení pinů, tak i výchozí nastavení připravené pro hardwarové SPI (konkrétně VSPI
), tak prostě program s hardwarovým SPI nefunguje! Respektive, program žádnou chybu nehlásí a běží. Běh nám dokazuje interní LED na pinu GPIO2
, která se pravidelně rozsvěcí, což signalizuje běh hlavní smyčky. Ale displej je celou dobu stále jen zhasnutý. 😒
Podle kontroly parametrů hardwarového řadiče SPI by měly být nastaveny stejné parametry jako jsou při použití SoftSPI, takže by vše mělo fungovat stejně. Ale prostě ne! Dokonce pokud tyto hodnoty (pro jistotu) nastavíme znova pomocí metody SPI.ini()
, displej pod taktovkou hardwarového SPI stále nefunguje. Nepomohlo ani přepojení displeje na druhou hardwarovou sběrnici SPI (HSPI
), ani různé experimenty s parametry komunikace.
V tuto chvíli opravdu netušíme, kde je problém. Je pravda, že použitý modul ESP32 WROOM-32 je již takovým veteránem různých našich pokusů a experimentů… Ale že by zrovna tento kus měl jen poškozený řadič hardwarového SPI, se zdá být jako dosti nepravděpodobné.
Pochopitelně nás situace nenechává klidnými a budeme dále hledat problém. Pokud by někdo věděl, kde a co děláme chybně, dejte nám, prosím, vědět. Za každou užitečnou radu budeme vděční!
Dnešní článek tedy skončil poněkud netradičně, ale i takové věci se ve světě bastlířů dějí! Je to svět pokusů, omylů a žádných pořádných manuálů… To je také důvod, proč tyto články píšeme, aby tam, kde můžeme poradit, jsme někomu pomohli.
A nyní se zkrátka karta obrátila! 😉
Závěr
V dnešním článku i přes jeho určitý rozpačitý závěr jsme si ukázali, jak lze ovládat OLED displej s řadičem SSD1306 pomocí sběrnice SPI – i když (zatím?) jen přes softwarově emulované SoftSPI. Seznámili jsme se s knihovnou ssd1306
, která je ale použitelná i pro I²C displej, takže se nemusíme omezovat jen na zde avizované SPI displeje. Ovládnutím jakéhokoliv displeje rázem naše budoucí projekty získávají na atraktivitě a možnosti poměrně hezkého výstupu a smysluplné interakce s uživatelem.
A na co se podíváme příště?
Zatím jsme stále načítali nějaká čidla, dnes zobrazovali texty a obrázky, ale stále se nám na stole nic nepohnulo! Tak proč se nyní nezkusit vydat třeba tímto směrem?