|
Raspberry Pi
35) Ovládání nestandardních grafických
displejů
3.část: Displej
pg12864lrf-nra-h (rozlišení 128x64 bodů)
Posledním displejem, který jsem připojil k RasPi je "pg12864lrf-nra-h"
Katalogový list je tu: http://www.farnell.com/datasheets/1310996.pdf
Na stránkách Farnellu se sice uvádí, že je to pětivoltový displej,
ale v katalogovém listu je uvedeno, že má napájení 3,3V.
Pětivoltové napájení jsem nezkoušel, ale na 3,3V funguje dobře.
V katalogovém listu jsou také nějak špatně označené vývody č.6 a č.7 (WR
a RD).
Uvádí se tam, že při zápisu do displeje musí být WR v "0" a RD
v "1".
Ve skutečnosti jsem ale musel zapojit displej tak, že při sériové
komunikaci má WR připojeno na "1" (+3,3V) a RD na "0" (GND).
Tento displej má proti předchozím grafickým displejům několik výhod.
1) Kromě paralelní komunikace (8 datových vodičů + Reset +
RS) dokáže
komunikovat i sériově -
- pouze pomocí 4 drátů SDA + SCL + Reset + RS), takže není potřeba ten
displej připojovat přes expander.
2) Nepotřebuje záporné napájení pro nastavení kontrastu
displeje. Kontrast je možné nastavit pomocí příkazu odeslaného do
displeje.
3) Jako podsvět jsou použity obyčejné LED diody, takže k podsvícení
není potřeba žádné vysoké napětí.
Zapojení vývodů podle katalogového listu:
Vývod |
Význam |
1 |
Vss - GND |
2 |
RES - reset - aktivní v nule |
3 |
CS - chip select - aktivní v nule |
4 |
RS - přepínaní "Příkazy" / "Data"
(někdy označeno jako C/D - Command / Data) |
5 |
P / S - volba paralelní ("1"), nebo sériové
("0") komunikace |
6 |
WR - zápis dat do displeje ???
- při sériové
komunikaci připojit na +3,3V |
7 |
RD - čtení dat z displeje ???
- při sériové komunikaci připojit
na GND |
8 |
D0 - paralelní data |
9 |
D1 - paralelní data |
10 |
D2 - paralelní data |
11 |
D3 - paralelní data |
12 |
D4 - paralelní data |
13 |
D5 - paralelní data |
14 |
D6 - paralelní data |
15 |
D7 - paralelní data |
16 |
Vdd - napájení +3,3V |
17 |
SCL - sériové hodiny - POZOR! -
není to I2C
komunikace |
18 |
SDA - sériová data - POZOR!
- není
to I2C komunikace |
19 |
Anoda podsvětu (odběr LED diod je asi 50mA při napájení
z +5V přes odpor 47 Ohmů) |
20 |
Katoda podsvětu - GND |
Pro připojení displeje jsem si zvolil jednodušší sériovou
komunikaci:
GPIO vývody si můžete zvolit podle potřeby, ale v tom případě
je třeba změnit jejich nastavení v programu.
Protože nemám žádný konektor jako protikus páskového
slídového kablíku, který je součástí displeje, připájel jsem k
displeji místo něj plochou "dvacetilinku" s roztečí žil 1mm, takže
ty žíly přesně sedí na původní vývody displeje. Ta milimetrová
dvacetilinka se trochu hůř shání, ale ve Farnellu mají všechno: http://cz.farnell.com/jsp/search/productdetail.jsp?sku=1440149
Software:
Displej má vnitřní grafickou paměť uspořádanou úplně
jinak, než minule popsané displeje.
Proto bylo třeba provést větší změny v ovládacím programu.
Program je upravený tak, že je možné použít font od
minulých displejů, který má znaky vysoké 8 bodů, definované po pěti mikrosloupcích zleva doprava.
V programu se pak provádí bitové otáčení definice znaku o 90°.
Nebo je možné použít jiný font, který má jednotlivé znaky široké 8
bodů, ale jsou definované po mikrořádkách zhora dolů.
Já jsem použil font z těchto stránek: http://ubicomp.teco.edu/hardware/
Zatímco minulé displeje měly pevně daný řádkový rastr,
do kterého bylo možné psát text, ale sloupce byly volně definovatelné
po jednotlivých bodech, u tohoto displeje je to naopak.
Text se může psát v libovolné vzdálenosti od horního okraje, ale v šířce
displeje je možné umístit znak jen na některou z 16 pozic.
Jednoduše řečeno - na řádku tohoto displeje se vejde jen 16 znaků.
To se mi moc nelíbilo, a tak jsem do programu přidělal podprogram, který
každý znak z fontu převede na jednotlivé body a ty pak pomocí funkce mem_plot() postupně vykreslí na displeji. Tento podprogram sice umožňuje
tisknout znaky na úplně libovolnou pozici na displeji, ale protože převádí
každý znak na jednotlivé body, tak je také dost pomalý. Proto se kreslení
znaků provádí jen v paměti, a na závěr je nutné použít funkci mem_dump()
pro přenesení obsahu paměti do displeje.
Tady je ukázka tří variant zobrazení nápisů.
V horní části je nápis zobrazený pomocí pomalého podprogramu na převádění
znaků na jednotlivé body, uprostřed je stejný font, ale zobrazení je ve
sloupcovém rastru se šířkou znaků 8 bodů.
Dole je pak použit jiný (tučný) font - opět v rastru 8x8 bodů.
Na RasPi je třeba mít nainstalovanou podporu pro ovládání
GPIO pinů přes Python.
Návod na instalaci je tady: http://www.raspberrypi-spy.co.uk/2012/07/install-rpi-gpio-library-in-raspbian/
Samotný ovládací program s ukázkou řízení displeje je tady: glcd12864-ser.py
Soubor s fontem je stejný, jako u dříve popisovaných displejů:
font.txt
Druhý (tučný) font : font2.txt
Testovací bitmapový obrázek je tu: malina.bmp
Všechny čtyři soubory si uložte do adresáře /home/pi/.
Připojte
displej podle schématu, které je uvedeno výše a zapněte napájení.
Pak v terminálu spusťte ukázkový program:
sudo python /home/pi/glcd12864-ser.py |
Na začátku ukázkového programu je část, kdy se
automaticky každou sekundu mění kontrast displeje.
V okamžiku, kdy budete vidět, že je nápis na displeji čitelný nejlépe,
zapamatujte si zobrazené číslo.
Toto číslo vložte do programu - do proměnné "defaultni_kontrast". Přednastavená
hodnota je 10, ale může být u každého displeje trochu jiná. Když zadáte
menší číslo, bude displej světlejší. Při větším čísle tmavne.
Všechny podprogramy jsou vysvětleny přímo v kódu, tak zde
uvedu jen jejich krátký popis:
disclear(pattern) |
Vyplní celý displej hodnotou proměnné "pattern"
- tím smaže displej při (pattern=0), nebo ho celý zaplní černými
body pro (pattern=255) .
Tuto funkci je možné využít na vyplnění celého displeje svislými čarami
(například při zadání hodnoty 0xAA , nebo 0xCC) |
malý font 8x8 |
znak(kod , x , supery) |
Zobrazí jeden znak s ASCII kódem "kod" na souřadnice
"x" (0 až 15),
"supery" (0 až 63) - horní strana znaku je na mikrořádce
"supery". |
slovo(text, x , supery) |
Zobrazí text (více znaků) na souřadnicích "x"
a "supery" (parametry stejné jako ve funkci "znak()"). |
malý font 5x8 |
znak2(kod , superx , supery) |
... stejné, jako funkce znak(), ale s úspornějším
zobrazením na libovolné pozici displeje. Po použití je třeba provést
mem_dump() |
slovo2(text, superx , supery) |
... stejné, jako funkce slovo(), ale s úspornějším
zobrazením na libovolné pozici displeje. Po použití je třeba provést
mem_dump() |
tučný font 8x8 |
znak3(kod , x , supery) |
... stejné, jako funkce znak(), ale s tučným
fontem. |
slovo3(text, x , supery) |
... stejné, jako funkce slovo(), ale s tučným
fontem. |
inverze(inv) |
Při inv=True nastane okamžitá inverze celého displeje.
Při inv=False se displej vrátí do normálního způsobu zobrazení. |
kontrast(k) |
Nastavení kontrastu displeje v rozsahu 0 až 15. |
plot(superx, supery, styl) |
Na souřadnicích "superx" (0 až 127) a "supery"
(0 až 63) zobrazí, smaže, nebo invertuje jeden bod. Jestliže styl=
0, provádí se mazání bodu, při styl=1 se bod zobrazí a při
styl=2 se provádí změna stavu bodu na displeji. |
mem_plot(superx, supery, styl) |
Stejná funkce jako předchozí "plot()", akorát
se body nezobrazují přímo na displeji, ale pouze v dočasném paměťovém
prostoru. Pomocí této funkce je možné rychlejší kreslení. Po použití
je ale nutné přenést obsah té dočasné paměti na displej pomocí
funkce "mem_dump()". |
mem_dump() |
Přenesení obsahu paměti na displej po použití příkazu
mem_plot(). |
h_cara(supery, od, do, styl) |
Vykreslení jednoduché horizontální čáry ve vzdálenosti
"supery" od horního okraje s možností definování začátku
a konce čáry (proměnné "od" a "do"). Parametr
"styl" je stejný jako ve funkci "plot()". |
vert_rolovani(textove_pole) |
Vertikální rolování celého displeje. V proměnné
"textove_pole" jsou nadefinovány jednotlivé řádky. |
load_bmp12864(jmeno_obrazku) |
Načtení dvoubarevného obrázku ze souboru do displeje.
Pozor na správný formát souboru! |
DEMO
Ukázka činnosti výše popsaného programu:
|
|
|