Kolejne zabawki:
Wyświetlacz LCD, ze sterownikiem HITACHI HD44780
Bardzo popularny, dostępny w wielu odmianach różniących się kolorem podświetlenia, liczbą wierszy i kolumn tekstu.
W dodatku niewiele kosztuje, w zależności od wersji (i sklepu, oczywiście) 10 - 30 złotych.
Opisów, jak go podłączyć i coś na nim wyświetlić znajdziecie w sieci wiele, nie będę ich tu powtarzał.
Skorzystamy z biblioteki wiringPi LCD devLib i skupimy się na tym, jak do Raspberry podłączyć więcej niż jeden wyświetlacz.
Da się? Ano da się, kilkanaście do jednego Raspberry.
No to zaczynamy.
Wyświetlacz ma 16 wyprowadzeń:
- Masa
- Zasilanie +5V, przez dwie diody w kierunku przewodzenia.
- Kontrast. Podajemy to napięcie między 0 a 5V, z potencjometru lub dzielnika zrobionego z dwu oporników.
- RS. Jeśli na to wyprowadzenie podamy stan niski, to stan linii D0-D7 zostanie potraktowany jako rozkaz, jesli wysoki - jako dane.
- RW. Zapis/Odczyt. Ponieważ do naszego wyświetlacza będziemy tylko pisać, to wyprowadzenie podpinamy na stałe do masy.
- E. Opadajęce zbocze sygnału na tym wyprowadzeniu spowoduje odczytanie i zinterpretowanie stanu magistrali danych D0-D7.
- D0. Bit 0 magistrali danych
- D1. Bit 1 magistrali danych
- D2. Bit 2 magistrali danych
- D3. Bit 3 magistrali danych
- D4. Bit 4 magistrali danych
- D5. Bit 5 magistrali danych
- D6. Bit 6 magistrali danych
- D7. Bit 7 magistrali danych
- A. +5V jako zasilanie podświetlenia wyświetlacza
- K. Masa zasilania podświetlenia wyświetlacza
Dlaczego zasilanie przez dwie diody?
Na łączówce GPIO jedynka logiczna to 3,3V. Dla wyświetlacza jedynka logiczna to 0,7xVDD (napięcia zasilającego), więc dla 5V będzie to 3,5V. Jeśli podepniemy pin GPIO z pinem wyświetlacza, to albo nie będzie działać, albo sygnał będzie podatny na zakłócenia.
Spadek napięcia na dwu diodach spowoduje, że VDD wyświetlacza spadnie do około 3,5V, więc napięcie logicznej jedynki wyniesie 2,45V.
Wyświetlacz może pracować w trybie 8 bitowym lub 4 bitowym. Tak go skonstruowano.
W trybie 8 bitowym używane są wszystkie linie magistrali danych, w trybie 4 bitowym linie D4 - D7.
Skorzystamy tu z tej drugiej opcji, trybu 4 bitowego - szkoda wyprowadzeń GPIO!
No to teraz kabelki:
Pin wyświetlacza | Podpinamy do |
---|---|
VSS | Masa, np. pin 6 (fizyczny) GPIO |
VDD | Zasilanie +5v, np. pin 2 (fizyczny) GPIO |
V0 | Podłączamy suwak potencjometru wpiętego pomiędzy VSS i VDD. Rezystancja - co tam Wam w łapy wpadnie, ja użyłem potencjometru montażowego 4,7kΩ |
RS | Połączymy z pinem GPIO.23. Później porozmawiamy o alernatywnych pinach. |
RW | Ponieważ do wyświetlacza będziemy tylko pisać, to wyprowadzenie łączymy z masą. |
E | Łączymy z pinem GPIO.25. |
D0-D3 | Nigdzie nie łączymy, nie potrzebujemy tych wyprowadzeń, będziemy korzystali z trybu 4 bitowego. |
D4-D7 | Łączymy kolejno do GPIO.29, GPIO.28, GPIO.27, GPIO.26. |
A | Łączymy z zasilaniem +5V |
K | Łączymy z masą |
Piny GPIO wybrałem arbitralnie, mogą to być dowolne inne piny GPIO, te jednak zostały użyte w przykładowych programach, które za chwilę omówimy, więc jeśli z jakiegoś powodu chcesz lub musisz użyć innych, wprowadź korekty w programach źródłowych.
Te akurat są wygodne, bo ładnie się grupują na lączówce GPIO, jedną 10 pinową wtyczką możemy podłączyć wszystko oprócz zasilania..
No i prościutki programik, żeby sprawdzić czy dobrze kabelki połączyliśmy.
#include <string.h> #include <stdio.h> #include <stdlib.h> #include <wiringPi.h>Potrzebny jest zbiór nagłówkowy wiringPi.h!
/* zmienne */ static int lcdHandle ;Prościutka funkcja która wyświetli tekst w kolumnie x i wierszu y ekranu wyświetlacza:
void wyswietl(int x, int y, char* tresc) { lcdPosition (lcdHandle, x, y) ; lcdPuts (lcdHandle, tresc) ; } /* S T A R T */ main (argc, argv) int argc; char *argv[]; {Inicjalizacja struktur biblioteki WiringPi:
if (wiringPiSetup() == -1) { printf("wiringPi-Error\n"); exit(1); }Teraz inicjalizacja naszego wyświetlacza.
int lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
Tu definiujemy jakiego typu wyświetlacza użyliśmy, w jakim trybie pracuje i gdzie podłączyliśmy sygnały.
Liczba wierszy, liczba kolumn, tryb (4/8 bitów), RS i E.
Kolejne 8 wartości to numery pinów GPIO do których podłączyliśmy magistralę danych wyświetlacza.
I tu parę słów wyjaśnienia.
Jeśli użyliśmy trybu 8 bitowego, wszystko proste i logiczne, kolejne pozycje parametrów funkcji lcdinit to D0, D1 itd. wyświetlacza.
W trybie 4 bitowym jednak, z jakiegoś powodu producent wykorzystał styki D4-D7 wyświetlacza, a nie D0-D3, zobacz: Piny
Mamy więc w lcdInit D0=29, D1=28, D2=27 i D3=26, ale bity te są fizycznie podłączone do D4, D5, D6 i D7 wyświetlacza.
lcdHandle = lcdInit (4, 16, 4, 25,23,29,28,27,26,0,0,0,0) ;Czyścimy ekran wyświetlacza:
lcdClear (lcdHandle) ;I w kolejnych wierszach wyświetlamy kolejne argumenty, z jakimi wywołaliśmy nasz program, dla uproszczenia wszystkie od zerowej kolumny.
wyswietl(0, 0, argv[1]); wyswietl(0, 1, argv[2]); wyswietl(0, 2, argv[3]); wyswietl(0, 3, argv[4]); }
Przepisujemy programik opisany na poprzedniej stronie lub ściągamy gotowy
Kompilujemy:
cc wyswlcd1.c -o wyswlcd1 -L/usr/local/lib -lwiringPi -lwiringPiDev
I uruchamiamy:
./wyswlcd1 "Ala ma kota" "Druga linia" "Trzecia linia" "Czwarta linia"
Jeśli wszystko poszło dobrze, na ekranie wyświetlacza coś takiego się pojawi:
Ale mieliśmy podłączyć dp Raspberry więcej wyświetlaczy!
Potrzebujemy 4 piny na dane, 2 na RS i E.
Do dyspozycji (w stanie jaki raspbian nam przygotował) mamy 17 pinów GPIO, wydawałoby się, że tylko dwa podłaczymy, bo 3*6 to już 18.
Nie jest tak źle, linie danych i RS mogą być wspólne dla wszystkich wyświetlaczy.
Skorzystają z nich dopiero jak na E (strobe) pojawi się opadające zbocze sygnału!
Potrzebujemy więc tylko 5 wspólnych pinów GPIO i po jednym oddzielnym na każdy wyswietlacz.
17-5=12, tyle wyświetlaczy możemy obsłuzyc.
Może nawet wiecej, bo wszystkich pinów GPIO rapberry ma 28, jeśli je przeprogramujemy, a kto nam broni, nawet 23 wyświetlacze podłączymy.
No to do dzieła. Podłączamy drugi wyświetlacz.
Wszystkie wyprowadzenia równolegle do pierwszego, za wyjątkiem E (strobe), który podepniemy do GPIO.24.
No to teraz rozbudowujemy nasz program.
Kilka zmian w programie, tu wyróżnionych pogrubioną czcionką.
Dla każdego wyświetlacza wykonujemy icdInit wskazując pin GPIO do którego podłączone jest jego wyprowadzenie E (strobe).
W poniższym kodzie piąty parametr lcdInit, piny 23 i 24.
Kolejne wyświetlacze programujemy analogicznie.
static int lcdHandle ; static int lcdHandle1 ;
void wyswietl(int x, int y, char* tresc) { lcdPosition (lcdHandle, x, y) ; lcdPuts (lcdHandle, tresc) ; } void wyswietl1(int x, int y, char* tresc) { lcdPosition (lcdHandle1, x, y) ; lcdPuts (lcdHandle1, tresc) ; }
lcdHandle = lcdInit (4, 16, 4, 25,24,29,28,27,26,0,0,0,0) ; lcdHandle1 = lcdInit (4, 16, 4, 25,23,29,28,27,26,0,0,0,0) ; if (atoi(argv[1]) == 0) { lcdClear (lcdHandle) ; wyswietl(0, 0, argv[2]); wyswietl(0, 1, argv[3]); wyswietl(0, 2, argv[4]); wyswietl(0, 3, argv[5]); } else { lcdClear (lcdHandle1) ; wyswietl1(0, 0, argv[2]); wyswietl1(0, 1, argv[3]); wyswietl1(0, 2, argv[4]); wyswietl1(0, 3, argv[5]); }
Uzupełniamy nasz program lub ściągamy gotowy
Kompilujemy:
cc wyswlcdn.c -o wyswlcdn -L/usr/local/lib -lwiringPi -lwiringPiDev
I uruchamiamy:
./wyswlcdn 0 "Pierwszy LCD" "Druga linia" "Trzecia linia" "Czwarta linia"
./wyswlcdn 1 "Drugi LCD" "Druga linia" "Trzecia linia" "Czwarta linia"
Jeśli wszystko poszło dobrze, na ekranie pierwszego wyświetlacza coś takiego się pojawi:
Drugi wyświetli:
Program tu opisany, dla łatwiejszego zrozumienia zasady działania starałem się maksymalnie uprościć, pozostawiłem jedynie niezbędne fragmenty.
Oczywiście, jak to na tym świecie już jest, nic za darmo. Każde uruchomienie programu w celu wyświetlenia treści powoduje wykonanie lcdInit dla wszystkich wyświetlaczy, so skutkuje ich wyzerowaniem, dodanie nowego wyświetlacza wiąże się z koniecznością modyfikacji kodu programu.
Jeśli użyjemy opisanych tu mechanizmów w bardziej rozbudowanym programie, niedogodności te znikną.
Wyświetlaczy opisanego tu typu używamy do wyświetlania instrukcji podczas badań alkomatem w naszym systemie kontroli trzeźwości i instrukcji tankowania paliwa w zakładowej stacji paliw