Obsługa modułu LCD W EP 4/2011 opublikowaliśmy opis modułu LCD z przyciskami (AVT1615) współpracującego z płytką Arduino oraz kompatybilną – AVTduino. W tym artykule pokażemy sposób obsługi programowej tego modułu oraz komponentów interfejsu użytkownika, które on zawiera: przycisków, potencjometru, generatora piezzo, diod LED oraz czujnika temperatury LM35.
Zacznijmy od przykładów praktycznych
rozwiązań, których będzie można użyć w sa- modzielnie opracowywanych aplikacjach. Na listingu 1 zamieszczono przykładowy program dla modułu AVT1615. Program ten przez termometr LM35 dołączony do nóżki Dodatkowe materiały na CD/FTP: ftp://ep.com.pl, user: 10925, pass: 87thc181 wyświetla komunikat na wyświetlaczu LCD, A1. Dzięki 8-bajtowej tablicy byte st[8]={…} • poprzednie części kursu mierzy napięcie na suwaku potencjometru, zdefiniowano symbol stopnia, który jest uży- odczytuje temperaturę, wyświetla umowny wany jako jednostka temperatury. numer naciśniętego przycisku oraz zaświeca W funkcji setup() za pomocą komendy Char(0, st), której argumentami są numer umieszczoną koło niego diodę LED. Dodatko- lcd.begin(16, 2) zdefiniowano rozdzielczość znaku (kod) oraz bajty definicji (w naszym wo, naciśnięcie przycisku jest sygnalizowa- zastosowanego wyświetlacza LCD. Pierwszy wypadku jest to tablica st[]). Komenda ana- ne dźwiękiem brzęczyka piezzo. parametr określa liczbę znaków w wierszu logReference(DEFAULT) ustala napięcie od- W Arduino do obsługi modułów wyświe- (kolumn) a drugi liczbę wierszy. Jak łatwo niesienia dla wewnętrznego przetwornika tlaczy z kontrolerem HD44780 jest przezna- domyślić się, w przykładzie zastosowano A/C mikrokontrolera na napięcie zasilające czona biblioteka LiquidCrystal (LCD) która wyświetlacz 2×16 znaków. Do utworzenia (w tym wypadku 5 V). Przetwornik mikro- umożliwia sterowanie modułem wyświetla- znaku stopnia służy komenda lcd.create- kontrolera będzie mierzył sygnały analogowe cza za pomocą interfejsu z 4- lub 8-bitową szyną danych. W tabeli 1 zamieszczono ko- Tabela 1. Komendy obsługi wyświetlacza LCD mendy dostępne w tej bibliotece. LiquidCrystal() Definiuje piny do których został dołączony LCD Niektóre z komend wymienionych w ta- begin() Definiuje rozdzielczość zastosowanego LCD beli 1 zastosowano w przykładowym pro- clear() Czyści ekran LCD gramie z listingu 1. Jak można zauważyć, home() Ustawia kursor na początku ekranu LCD w programie w pierwszej kolejności dołączo- setCursor() Ustawia kursor w zadanym miejscu LCD no bibliotekę obsługi LCD – LiquidCrystal.h. write() Zapisuje znak do LCD Następnie zadeklarowano stałe definiujące print() Zapisuje znak lub znaki do LCD wyprowadzenia, do których dołączono dio- cursor() Włącza kursor dy LED, klawisze i brzęczyk piezzo. Dla lep- noCursor() Wyłącza kursor szej czytelności programu nadano im łatwe blink() Włącza miganie kursora do zapamiętania nazwy. Numery wyprowa- noBlink() Wyłącza miganie kursor dzeń są zgodnie z opisem na płytkach Ardu- display() Włącza ekran LCD ino Uno i Avtduino LCD. Dalej, za pomocą noDisplay() Wyłącza ekran LCD komendy LiquidCrystal(rs, enable, d4, d5, d6, scrollDisplayLeft() Przesuwa zawartość LCD w lewo d7) zgodnie ze schematem ideowym przypi- scrollDisplayRight() Przesuwa zawartość LCD w prawo sano wyprowadzenia, do których został dołą- czony LCD. W dalszej części programu utwo- autoscroll() Automatyczne przesuwanie zawartości na LCD rzono zmienne wykorzystywane do oblicze- noAutoscroll() Wyłączenie automatycznego przesuwania zawartości na LCD nia wartości zmierzonego napięcia z suwaka leftToRight() Ustawia kierunek zapisu tekstu od prawej do lewej potencjometru dołączonego do nóżki A0 rightToLeft() Ustawia kierunek zapisu tekstu od lewej do prawej oraz do obliczenia temperatury zmierzonej createChar() Umożliwia zdefiniowanie własnego znaku
86 ELEKTRONIKA PRAKTYCZNA 6/2011
Kurs Arduino
Listing 1. Przykładowy program dla modułu AVT11615 o napięciu od 0 V do 5 V z rozdzielczością
/* 10-bitow. Komendy pinMode() definiują spo- Przykład programu do obsługi modułu AVT1615 z: - wyświetlaczem LCD 2x16 znaków sób pracy portów I/O mikrokontrolera. Linie, - 4 diodami LED - 4 przyciskami które sterują diodami LED oraz generatorem - brzęczykiem piezzo piezzo skonfigurowano jako wyjścia, a linie, - czujnikiem temperatury LM35 */ do których dołączono przyciski jako wejścia. Za pomocą funkcji digitalWrite() dołączono #include <LiquidCrystal.h> //biblioteka obsługi LCD rezystory zasilające pull-up, które polaryzują const int Led1 = 13; //przypisanie aliasów do pinów portów wejścia. Przyciśnięcie przycisku zmienia po- const int Led2 = 12; ziom dołączonego wejścia na niski. const int Led3 = 11; const int Led4 = 10; W funkcji loop() znajduje się program const int SW1 = 3; główny. W pierwszej kolejności za pomocą const int SW2 = 2; const int SW3 = 1; komendy lcd.clear() jest czyszczony ekran const int SW4 = 0; const int Buzzer = A5; LCD. Następnie, za pomocą komendy lcd.set- Cursor(4, 0) kursor jest ustawiany w pierw- LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //konfigurowanie linii do których został dołączony LCD szym wierszu i 5 kolumnie LCD (współ- int wart_pot; //zmienna na wartość zmierzona z potencjometru rzędne numerowane są od 0). Komenda lcd. int wart_czuj; //zmienna na wartość zmierzonej z czujnika temperatury print(„Arduino”) wyświetla od ustawionej float wart_nap; //zmienna na wartość zmierzonego napięcia float temperatura; //zmienna na wartość zmierzonej temperatury pozycji kursora komunikat Arduino. Jako pa- byte st[8] = { //tablica znaku stopnia dla wyświetlacza LCD rametr funkcji lcd.print() można użyć stałych B00100, w cudzysłowie lub zmiennych typu: char, B01010, B00100, byte, int, long, string. Funkcja ta ma również B00000, drugi opcjonalny parametr, który umożliwia B00000, B00000, formatowanie wyświetlanych liczb. Dozwo- B00000, }; lone są następujące ich formaty: DEC (dzie- siętny), BIN (binarny), OCT (ósemkowy) void setup() { //funkcja inicjalizacji lcd.begin(16, 2); //konfigurowanie rozdzielczości LCD i HEX (szesnastkowy). Następnie, w pro- lcd.createChar(0, st); //funkcja utworzenia własnego znaku z tablicy st gramie przykładowym za pomocą komendy o kodzie 0 analogReference(DEFAULT); //konfigurowanie napięcia odniesienia analogRead(A0) jest odczytywane napięcie //dla przetwornika A/C - domyślnie 5V pinMode(Led1, OUTPUT); //konfigurowanie I/O, do których są zmierzone przez przetwornik A/C na wejściu //dołączone diody LED A0. Jak pamiętamy, jest to napięcie z suwaka pinMode(Led2, OUTPUT); pinMode(Led3, OUTPUT); potencjometru. Dla uniknięcia błędów po- pinMode(Led4, OUTPUT); pinMode(Buzzer, OUTPUT); //konfigurowanie I/O, do której jest miar jest wykonywany 20 razy w pętli FOR, //dołączony brzęczyk piezzo jego wynik jest sumowany w zmiennej wart_ pinMode(SW1, INPUT); //konfigurowanie I/O, do których są //dołączone przyciski pot, a następnie jest obliczana średnia aryt- pinMode(SW2, INPUT); metyczna z wyników pomiarów. Za pomocą pinMode(SW3, INPUT); pinMode(SW4, INPUT); wyrażenia wart_nap=(5.0*wart_pot)/1024.0 digitalWrite(SW1, HIGH); //dołączenie wewnętrznych rezystorów //zasilających wartość obliczonej średniej jest zamieniana digitalWrite(SW2, HIGH); na napięcie. Stała „5.0” to napięcie odnie- digitalWrite(SW3, HIGH); digitalWrite(SW4, HIGH); sienia dla przetwornika, natomiast „1024” to digitalWrite(Led1, HIGH); //wyłączenie diod LED jego rozdzielczość. Tak przeliczona wartość digitalWrite(Led2, HIGH); digitalWrite(Led3, HIGH); zmiennej zostaje wyświetlona w drugiej linii digitalWrite(Led4, HIGH); digitalWrite(Buzzer, HIGH); //wyłączenie brzęczyka piezzo wyświetlacza LCD. } Podobnie w dalszej części programu jest void loop() { //pętla główna programu wykonywany pomiar temperatury za pomo- lcd.clear(); //czyszczenie LCD lcd.setCursor(4, 0); //ustawienie kursora w 5 kolumnie cą pomiaru napięcia na wyjściu czujnika //pierwszego wiersza LM35. Zmiana temperatury o 1ºC powoduje lcd.print(„Arduino”); //wyświetlenie na LCD napisu Arduino //pomiar napięcia z potencjometru i dodanie wyniku do wart_pot wzrost napięcia na wyjściu czujnika tempe- for (int i = 0; i < 20; i++) { //pętla wykonywana 20 razy ratury o 10 mV. Łatwo wywnioskować, że wart_pot = wart_pot + analogRead(A0); } zmiana temperatury o 10ºC będzie odpowia- //obliczenie średniej arytmetycznej z 20 pomiarów wart_pot = wart_pot / 20; dała zmianie napięcia wyjściowego czujnika //przeliczenie odczytanej wartości na napięcie o 100 mV. Temperatura jest odczytywana za wart_nap=(5.0*wart_pot)/1024.0; //ustawienie kursora w pierwszej pozycji drugiego wiersza LCD pomocą funkcji analogRead(A1) mierzącej lcd.setCursor(0, 1); lcd.print(„U=”); //wyświetlenie napisu U= równoważne jej napięcie z czujnika LM35 lcd.print(wart_nap); //wyświetlenie napięcia na wejściu A1. Również w tym wypadku jest lcd.print(„V”); //wyświetlenie znaku V wykonywane 20 pomiarów, z których jest ob- for (int i = 0; i < 20; i++) { //pętla wykonywana 20 liczana średnia arytmetyczna. Następnie za //pomiar napięcia z czujnika temperatury i dodawanie wart_czuj wart_czuj = wart_czuj + analogRead(A1); pomocą wyrażenia temperatura=(5.0*wart_ } //obliczenie średniej arytmetycznej z 20 pomiarów czuj*100)/1024.0 liczba odczytana z rejestru wart_czuj = wart_czuj / 20; przetwornika A/C jest zamieniana na tempe- //przeliczenie wartości na stopnie Celsjusza temperatura=(5.0*wart_czuj*100)/1024.0; raturę. Wartość temperatury jest wyświetla- //ustawienie kursora na pozycji 9 drugiego wiersza LCD lcd.setCursor(9, 1); na na wyświetlaczu w pozycji wskazywanej lcd.print(„T=”); //wyświetlenie napisu T= lcd.print((long)temperatura); przez komendę lcd.setCursor(9, 1). Komenda //wyświetlenie wartości temperatury zaokrąglonej do pełnych stopni lcd.write(0); //wyświetlenie znaku stopnia lcd.write(0) powoduje wyświetlenie po war- tości temperatury symbolu stopnia.
ELEKTRONIKA PRAKTYCZNA 6/2011 87
KURS
W dalszej części programu umieszczo- Listing 1. c.d.
no cztery bloki podobnych instrukcji obsłu- lcd.print(„C”); //wyświetlenie znaku C gujących przyciski S1...S4 z diodami oraz //sprawdzenie czy naciśnięto przycisk S1 if (digitalRead(SW1) == LOW) { brzęczyk piezzo. Ich działanie omówimy na digitalWrite(Led1, LOW); //zaświecenie LED1 przykładzie instrukcji odczytujących stan digitalWrite(Buzzer, LOW); //włączenie brzęczyka lcd.clear(); //czyszczenie LCD przycisku S1, ponieważ pozostałe działają //ustawienie kursora w pierwszym rzędzie i drugiej kolumnie lcd. w ten sam sposób. setCursor(2, 0); lcd.print(„Przycisk S1”); //wyświetlenie nazwy przycisku Za pomocą funkcji digitalRead(SW1) jest //oczekiwanie na zwolnienie przycisku S1 while(digitalRead(SW1) == LOW); odczytywany stan wejścia, do którego dołączo- } else { //w przeciwnym razie no przycisk S1. Następnie program sprawdza, digitalWrite(Led1, HIGH); //wyłączenie diody LED1 digitalWrite(Buzzer, HIGH); //wyłączenie brzęczyka czy odczytano poziom niski. Jeśli tak, to naci- } śnięto przycisk i zostają wykonane instrukcje if (digitalRead(SW2) == LOW) { //sprawdzenie czy naciśnięto S2 zawarte w warunku IF. Jako pierwsza jest za- digitalWrite(Led2, LOW); digitalWrite(Buzzer, LOW); świecana dioda LED1 za pomocą komendy di- lcd.clear(); gitalWrite(Led1, LOW). Kolejna instrukcja – di- lcd.setCursor(2, 0); lcd.print(„Przycisk S2”); gitalWrite(Buzzer, LOW) – powoduje załączenie while(digitalRead(SW2) == LOW); } else { brzęczyka piezzo. Następnie jest czyszczony digitalWrite(Led2, HIGH); ekran LCD, pozycjonowany kursor oraz wy- digitalWrite(Buzzer, HIGH); } świetlany komunikat informujący o numerze wciśniętego przycisku. W pętli while(digital- if (digitalRead(SW3) == LOW) { //sprawdzenie czy naciśnięto S3 digitalWrite(Led3, LOW); Read(SW1) == LOW) następuje oczekiwanie digitalWrite(Buzzer, LOW); lcd.clear(); na zwolnienie przycisku. Po jej zakończeniu są lcd.setCursor(2, 0); wykonane instrukcje digitalWrite(Led1, HIGH), lcd.print(„Przycisk S3”); while(digitalRead(SW3) == LOW); digitalWrite(Buzzer, HIGH) wyłączające diodę } else { digitalWrite(Led3, HIGH); LED oraz brzęczyk piezzo. digitalWrite(Buzzer, HIGH); Kolejne bloki programowe w taki sam } sposób obsługują pozostałe przyciski i diody if (digitalRead(SW4) == LOW) { //sprawdzenie czy naciśnięto S4 LED. Analogicznie, naciśnięcie przycisku S2 digitalWrite(Led4, LOW); digitalWrite(Buzzer, LOW); spowoduje zaświecenie się LED2, S3 zapali lcd.clear(); lcd.setCursor(2, 0); LED3 itd. Na ekranie LCD będą wyświetlane lcd.print(„Przycisk S4”); odpowiednie komunikaty, a naciśnięcie każ- while(digitalRead(SW4) == LOW); } else { dego przycisku będzie sygnalizowane przez digitalWrite(Led4, HIGH); digitalWrite(Buzzer, HIGH); brzęczyk piezzo. Program kończy się instruk- } cją delay(300), która powoduje zwłokę o cza- delay(300); //opóźnienie o 300ms sie trwania 300 ms. } //koniec pętli głównej Więcej informacji na temat komend ob- sługujących wyświetlacz LCD można zna- leźć na stronach internetowych Arduino Przyciski, w które jest wyposażony zestaw W kolejnym odcinku kursu omówimy w informacjach dotyczących zastosowania AVT1615 umożliwiają realizację interfejsu podobny moduł, jednak wyposażony w wy- biblioteki LiquidCrystal. użytkownika umożliwiającego na przykład świetlacze LED. Umożliwia on na przykład wprowadzanie nastaw. Niewątpliwym atu- zbudowanie miernika panelowego, zegara Podsumowanie tem są również diody LED i brzęczyk, któ- i innych urządzeń. Jednymi z najważniej- Moduł LCD zapewne będzie jednym rych można użyć do sygnalizowania stanu szych cech Arduino są bowiem prostota z najczęściej stosowanych we własnych apli- budowanego przez siebie urządzenia, sy- użycia i niesamowita wręcz elastyczność kacjach. Uniwersalny, umożliwiający wy- gnalizowania alarmów itp. Mam nadzieję, platformy umożliwiająca różnorodne jej za- świetlanie liczb, komunikatów tekstowych, że zaprezentowane przykłady obsługi wyja- stosowanie. prostych ikon i pasków postępu na pewno śniają jak można użyć tych elementów we Marcin Wiązania będzie chętnie używany do różnych zadań. własnym projekcie. marcin.wiazania@ep.com.pl
Oferta dla prenumeratorów Elektroniki Praktycznej
Avtduino specjalnie z myślą o elektronikach-praktykach! Od numeru EP 04/2011 rozpoczęliśmy za darmo jedną, wybraną płytkę drukowaną kurs programowania mikrokontrolerów AVR modułu rozszerzenia dla zestawu Avtduino z użyciem bezpłatnego środowiska progra- (zgodne z Arduino), dla których przykłady mistycznego Arduino. Kurs będzie się opierał aplikacji przedstawimy w ramach kursu publi- na przykładach przygotowanych dla pły- kowanego na łamach czasopisma. tek rozszerzających do bazy (kompatybilnej z systemem modułów Arduino) wyposażonej Pierwsze artykuły kursowe o Arduino m.in. w mikrokontroler ATmega, opisanej opublikowaliśmy w EP 4/2011 na stronach: w EP1/2011 (odpowiednik Arduino Duemila- 96 i 98. nove, AVT-5272). Opis pierwszego modułu rozszerzającego Dla prenumeratorów Elektroniki Prak- do płyty bazowej Avtduino opublikowaliśmy tycznej przygotowaliśmy niespodziankę: w Elektronice Praktycznej 4/2011 na stronie wszystkim prenumeratorom papierowej wer- 47 (AVT-1615), kolejnego w bieżącym nume- Płytka bazowa systemu Avtduino będąca bazowym sji miesięcznika w grudniu 2011 zaoferujemy rze na stronie 55 (AVT-1616). rozwiązaniem dla uczestników kursu