← zpět na zápisky z Arduino projektů
Naše první pokusy s OLED displejem. Já vím, zkratka OLED už sama o sobě v sobě obsahuje slovo displej, ale stejně tomu tak všichni říkají :-) OLED mají nízkou spotřebu a dobrý zobrazovací kontrast (svítí jen to, co svítit musí). Tak jsme taky nějaké chtěli vyzkoušet.
Rozhodně se hodí vědět, jaký přesně displej vlastně držím v ruce. To usnadní jeho ovládání :-) Jinak nejsou potřeba asi žádné speciální znalosti.
- OLED displej s I2C, např. SSD1306 (Aliexpress)
OLED displej, který jsme využili, má úhlopříčku 0,96" a rozlišení 128×64 pixelů. Připojili jsme ho přes rozhraní I2C. To komunikuje na 2 pinech SDA
(data) a SCL/SCK
(clock). Tyto má Arduino Uno schováno na analogových pinech A4 (SDA)
a A5 (SCL/SCK)
(zdroj).
K ovládání displeje se dále hodí knihovna u8g. Asi nejtěžším úkolem bylo zjistit, co přesně máme za displej a jakým konstruktorem knihovnu inicializovat. Nutno říci, že na displeji samotném jsme příliš vodítek nenašli.
Někdy můžete natrefit na displej, který je dvoubarevný. Nejde většinou o plnohodnotnou dvoubarevnost, ale jistá část displeje se zobrazuje vždy pevně jednou barvou a zbytek druhou. Barvu tak nenastavujete při vykreslování jako parametr, ale volíte ji umístěním na displeji.
Texty se na displeji vypisují metodou drawStr. Fonty se nastavují metodou setFont a je z čeho vybírat.
Následně děti projevily velký zájem zobrazovat na displej i něco jiného než jen texty různých velikostí. Postup je následující:
- Namalovat obrázek ve svém oblíbeném grafickém programu. Je dobré si nastavit velikost papíru na rozlišení displeje (např. 128×64), abychom se pak vešli. Pokud je displej jednobarevný či falešně dvoubarevný, je dobré kreslit pouze černou na bílem podkladu. Výsledný obrázek ořezat na minimální velikost.
- Pomocí programu pro převod bitmapy do kódu převést obrázek. Převod je vlastně pouhý převod černých pixelů na zápis v šestnáctkové soustavě (hexa) do zdrojového kódu tak, aby bylo možné ho nahrát do displeje.
- K převodu jsme využili program Image2Code napsaný v Javě (stačí pouze soubor Image2Code.jar, neinstaluje se, stačí spustit). Pokud Javu na počítači zatím nemáte, je potřeba doinstalovat. Pro Linux třeba takto:
sudo apt-get install default-jre
Program se pak spouští z příkazové řádky
java -jar Image2Code.jar
Ale je samozřejmě možné využít i jakýkoli jiný program, např. LCD image converter, který běhá na Windows, ale je možné ho zkompilovat i pro Linux - a celkově vypadá vymazleně.
Výsledný hexa kód nakopírovat do zdrojového souboru pro Arduino.
const uint8_t veselySmajl[] PROGMEM = {
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,
...
...
...
};
Klíčové slovo PROGMEM
zde zařídí, že celá bitmapa nebude uložena v operační paměti Arduina - té máme totiž obvykle velmi málo (Uno R3 = 2 KiB), ale protože se nebude v programu měnit (je konstantní), může být umístěna do tzv. flash paměti, kde leží i náš program (Uno R3 = 32 KiB). Více o rozdělení a druzích pamětí si lze přečíst zde, práce s PROGMEM je vysvětlena zde.
Ještě potřebujeme vědět, jaké má obrázek rozměry. Šířku vydělíme osmi a zaokrouhlíme nahoru (= počet bajtů, které jsou na řádku), výšku pak necháme, jak je. Pro vykreslení slouží funkce drawBitmapP().
//sirka obrazku = 65 -> 9 bajtu na radek
// vyska obrazku = 57
drawBitmapP(5, 5, 9, 57, veselySmajl);
Možná někoho napadne, proč není potřeba následně ve volání drawBitmapP
kopírovat data bitmapy z flash paměti do operační (pomocí nějaké z metod rozhraní pgmspace), když to návody u klíčového slova PROGMEM
ukazují. Je to proto, že knihovna u8g již předpokládá, že bitmapu ve flash paměti máme.
Ukázka z kódu knihovny v těle drawBitmapP
u8g_Draw8Pixel(u8g, x, y, 0, u8g_pgm_read(bitmap));
Knihovna u8g využívá koncept redraw - je potřeba neustále obnovovat stav displeje opakovaným překreslováním.
void loop(void) {
u8g.firstPage();
do {
draw();
} while(u8g.nextPage());
// po nejake dobe prekresli displej
delay(1000);
}
{% include_relative oled_txt.ino %}
{% include_relative oled_pic.ino %}
- Jakékoliv hrátky s displejem. Kombinace s ručními blikači, automatickými blikači, apod.
- Je možné vytvořit jednoduché hry, přeci jen OLED displej dává poněkud sofistikovanější zobrazovací možnosti. Spolu s tlačítky je pak možné vyhodnocovat odpovědi hráče nebo hru přímo ovládat.
- Nejvíce nás potrápila detekce displeje, pak správný konstruktor, nakonec zapojení na SDA/SCK na Arduinu (nevěděl jsem, že jsou na pinech A4/A5). Ovládání přes knihovnu u8g bylo naopak už docela lehké. Pak jsem se potrápil při vysvětlování
PROGMEM
, ale je to zase hezká příležitost jak objasnit dětem trochu paměťové uspořádání Arduina. - Náš OLED displej je sice maličký, ale je to displej a to dává všem projektům úplně jiný rozměr.
- Rozhraní
I2C
není zrovna nejrychlejší (400 kHz), chtělo by toSPI
(až 20 MHz), ale to náš konkrétní displej zdá se neumí. Takže rychlé animace asi nebudou.