V minulých lekcích (úvodní povídání a pokračování) jsme si povídali o znakových displejích. V dnešní lekci se zaměříme na grafické lcd displeje. Je jich spousta druhů s různými verzemi a různými rozměry displeje. S verzemi je nutné, pokud si koupíte něco exotického, občas v programu elaborovat, ale to si necháme spíše na konkrétní případ na schůzku. Velikostně je asi nejčastější verze, kterou vám také doporučuji – verze s rozměry 128×64 pixelů.
Grafický displej funguje podobným způsobem jako znakový displej co se týče zapojení. Znakový displej zobrazuje ve znakových maticích. Grafický displej se neomezuje na znakové matice, protože celá jeho zobrazovací plocha je jednou velkou maticí na které lze samostatně ovládat každý pixel. Z těchto možností tedy lze odvodit, že způsob programování grafického displeje, jestliže nám nabízí takovéto možnosti bude o něco složitější.
Knihovna U8glib
Chceme-li pracovat s grafickým displejem LCD 128×64 využijeme pro programování arduina knihovnu U8glib (k dispozici je i inovovaná verze této knihovny U8G2). Tato knihovna má poměrně přehlednou vlastní wikipedii, ze které se dá leccos zjistit. V této lekci se budeme věnovat hlavně příkazům pro modifikaci textu.
Základní součásti programu
V úvodu programu se příkazem include definuje knihovna se kterou budeme dál pracovat. Na dalším řádku je definován typ displeje se kterým má program dál pracovat. Knihovna U8glib je použitelná pro velké množství displejů různých typů od různých výrobců. Tyto displeje mohou mít různou kapacitu, rozlišení, čipovou sadu, nebo různou velikost RAM atd.. Proto pokud si po instalaci knihovny načtete vzorový kód v některých příkladech, naleznete v úvodu množství zakomentovaných řádků ve kterých si odkomentováním můžete zvolit právě aktuální verzi lcd se kterou pracujete. Zvolil jsem si „svou“ verzi lcd a zbytek nepotřebných řádek jsem smazal. Pokud vlastníte jiný typ grafického lcd, bude třeba experimentovat a zkusit různé typy definicí. Moje inicializační sekvence byla „U8GLIB_ST7920_128X64_1X u8g(13, 10, 11);“ a ano parametry v závorce jsou čísla pinů, ke kterým jsou připojeny komunikační vodiče a lze je podle potřeby změnit.
Následuje void draw(). Zde je definován obsah displeje, který bude vykreslený. V našem případě je příkazem setFont deklarován font ve kterém bude text na displeji zobrazen a posléze příkazem drawStr() deklarována pozice a obsah textového řetězce, který bude zobrazený na displeji.
Ve voidu setup() je možné ještě nastavit základní parametry fungování displeje jako je intenzita osvitu, případně zda displej bude fungovat v režimu „bílá na modré“, nebo v režimu „modrá na bílé“. Pokud se v setupu žádné parametry pro displej nenastaví, zobrazuje s přednastavenými parametry (není potřeba v setupu nastavovat vůbec nic).
V posledním voidu loop je s každým průběhem spouštěna překreslovací sekvence, která spouští a vykresluje void draw() (případně jiný vámi nadefinovaný void). Celý obsah loopu je pak ještě doplněn pauzou, kterou si opět můžete upravit k obrazu svému. Kratší pauza zlepšuje rychlost vykreslování a zvyšuje zátěž pro desku a displej, delší pauza snižuje nároky na vykreslování ale je vhodnější pro sestavy, kde není problémem pomalejší reakce na změny.
Předchozí odstavce se vztahují k následujícímu kódu. Kód je komentovaný, takže i procházením kódu si můžete ozřejmit základní součásti programu pro zobrazování na grafickém displeji.
#include „U8glib.h“ //vložená knihovna U8GLIB_ST7920_128X64_1X u8g(13, 10, 11); //typ lcd /* void ve kterém je definován obsah, který bude vykreslený */ void draw(void) { u8g.setFont(u8g_font_unifont); u8g.drawStr( 0, 22, „Hello World!“); } /* celkové nastavení vlastností displeje – barva, intenzita světla atd.*/ void setup(void) { if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); // white } else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3); // max intensity } else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1); // pixel on } else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); } pinMode(8, OUTPUT); } /* void loop ve kterém se vykresluje pravidelně obsah displeje*/ void loop(void) { // začátek vykreslovací sekvence u8g.firstPage(); do { draw(); //void jehož obsah je vykreslován } while( u8g.nextPage() ); // konec vykreslovací sekvence delay(50); //pauza mezi jednotlivými aktualizacemi obsahu } |
Prostor displeje
Jak již z označení displeje vyplývá, pro zobrazení textu máme k dispozici prostor 128×64 pixelů v rámci kterého lze pomocí souřadnic umístit jakýkoliv element (v našem případě se budeme bavit samozřejmě o umístění textu). Pro zobrazení textu lze použít dvě rutiny – příkaz setFont(), který by měl být deklarován jako prvý. Tímto příkazem je možné určit v jakém fontu bude text zobrazen (podrobněji v dalším odstavci). Následuje příkaz drawStr(), kterým arduinu říkáme na jakých souřadnicích bude umístěn daný text a jaký bude obsah tohoto textu. Logiku umísťování a situace se kterými se můžete setkat jsem zpracoval v následujících obrázcích.
Znakové sady
Texty, které můžeme zobrazovat na displeji, můžeme zobrazovat v různých znakových fontech. Sepsané je můžeme nalézt třeba zde. U některých fontů, v jejich názvech můžeme nalézt rozměry v pixelech, ze kterých je možné odvodit jejich výsledné rozměry na ploše. U zbytku je třeba vše zkoušet, dokud nedopadne výsledek k vaší spokojenosti.
Následující tabulka demonstruje použití příkazu setFont. Tato funkce má jeden jediný parametr a to je název fontu, který chceme pro zobrazení použít v závorkách. Všechny zobrazené textové řetězce za tímto příkazem budou na displeji zobrazené ve zvolené znakové sadě, dokud nebude provedena změna zadáním dalšího příkazu setFont. V tabulce jsem zobrazil pro přehlednost pouze jeden void, nejedná se o celý program (ten si můžete stáhnout na konci lekce).
void displej1() { u8g.setFont(u8g_font_5x8); u8g.drawStr(2, 20, „ondranauci.cz“); u8g.setFont(u8g_font_6x10); u8g.drawStr(2, 30, „ondranauci.cz“); u8g.setFont(u8g_font_7x13); u8g.drawStr(2, 42, „ondranauci.cz“); u8g.setFont(u8g_font_8x13); u8g.drawStr(2, 54, „ondranauci.cz“); } |
Zobrazování proměnných
Pokud by si někdo v takto pokročilé fázi nemohl vzpomenout co jsou to proměnné a jak je používat, nechť si naordinuje krátké opakování v lekci o proměnných: lekce o proměnných. Proměnné využijete i při zobrazování například hodnot naměřených na čidlech, nebo při výpisu různých stavů.
Sekvence pro zobrazení hodnoty proměnné se provádí pomocí dvou příkazů. V prvé fázi příkazem setPrintPos() – určíte místo na displeji odkud se bude obsah proměnné zobrazovat (je to stejný systém souřadnic, jako v případě příkazu drawStr()). Po určení pozice pak vypisujete obsah proměnné příkazem print(). Parametr v závorce je název zobrazované proměnné (v našem případě se jedná o proměnnou „a“). V případě našeho příkladu se hodnota proměnné a mění vždy o +1 s každým průběhem zobrazení. V tabulce jsem zobrazil pro přehlednost pouze jeden void, nejedná se o celý program (ten si můžete stáhnout na konci lekce).
void displej4() { u8g.setFont(u8g_font_5x8); u8g.drawStr(2, 10, „Hodnota promenne: „); u8g.setPrintPos(100, 10); u8g.print(a); } |
Úkoly:
1, Vložte na displej dva vlastní texty na různých pozicích
2, Vytvořte program, který bude na základě stisku tlačítka zobrazovat textové hlášení na displeji
3. Vytvořte program, který po stisku tlačítka změní pozici textu na displeji
Programy z článku ke stažení
Program GrapicsLcd-Hello pro vykreslování textu na grafickém lcd 128×64 popisovaném v tomto článku
Program GrapicsTex1 pro vykreslování textu na grafickém lcd 128×64 popisovaném v tomto článku
Dobrý den,
jak zarovnat numero (rozsah -30,0 až 99,9) vpravo na displeji OLED 0,99″ 128×64
případně různě proměnný text, no i na střed
Děkuji
JK
Dobrý den
Jako první bych zkusil prozkoumat dokumentaci použité knihovny, jestli tuto možnost nenabízí. Pokud ne, pak bych šel ryze programovou cestou – zjistit počet znaků v řetězci a z tohoto údaje vypočítat potřebné umístění začátku řetězce.