1602 LCD kijelző (ATtiny85 alaplappal is…)

Tartalom:

  • I2C illesztővel kiegészített LCD kijelző összekötése az Arduino-val
  • LCD kijelző használata az ATtiny85 alaplappal (kis memória a kevés kivezetés)
  • Kijelző használathoz szükséges programkönyvtár telepítése
  • Több kijelző használata egyszerre (kijelző címének változtatása)
  • Karaktertábla használata, saját karakterek (magyar ékezetesítés megvalósítása)
  • Példaprogram a használat megértéséhez

———————————————————————————————-

(Kedves olvasó! Ezt a leírást 2021 október elején kénytelen voltam javítani. Évekig nem vettem észre, hogy a leírásban LCD kijelző kezelő könyvtár telepítési leírása rossz! A hiba úgy derült ki, hogy kénytelen voltam feltelepíteni újra az Arduino fejlesztő környezetet a gépemre, és amikor a telepítésben az I2C busszal működő LCD kijelzőhöz értem (a saját leírásomat használtam), semmi nem működött. Ekkor vettem észre, hogy ebben a leírásban nem az I2C buszon működő könyvtárat telepítettem, hanem egy olyan programkönyvtárat, ami az LCD kijelzőt illesztő nélkül kezeli, sok-sok kimenetet elhasználva az Arduino kivezetések közül. Tehát ha régebben olvastad ezt a leírást, akkor valószínűleg nem működött a kijelző. A hibát az okozta, hogy sok programkönyvtárat kipróbálok a munkám során, és valami összekeveredett! Immár jó a könyvtár telepítési leírás, és az összes LCD kijelzőt használó programom működik, ha az itt megadott telepítési leírást követed! Bocsi!)

A kereskedelemben igen sokféle LCD kijelző kapható. Egy kezdőnek a legegyszerűbb és legolcsóbb a 2 soros soronként 16 karakteres kijelző használata. A kijelző ára 500Ft környékén mozog, így nem nagy beruházás. Gyengén látóknak (mint jómagam) szükség lehet nagyobb karakterméretű de teljesen azonos működésű típusra. A Chipcad-nél találtam 3000Ft környékén ilyen kijelzőt, ennek mérete óriási, messziről olvasható!
A kijelzőnek igen sok kivezetése van, így az Arduino Uno R3 panelen alig marad valami, ha így akarjuk bekötni. Szerencsére kapható hozzá egy kiegészítő áramkör kb. 300Ft értékben, ami I2C buszra illeszti a kijelzőt, így összesen csak két kivezetésre lesz szükségünk. Az I2C busz már “gyárilag beépítésre került az Az Arduino Uno R3-ba (illetve az ATmega chipekbe), így azt szinte azonnal használatba vehetjük. Az Arduino UNO esetén a programmemória és a belső RAM mérete nem szab határokat, kedvünkre válogathatunk a rengeteg előre elkészített programkönyvtár közül. Azonban a kicsi alaplapok pl. az ATtiny85, melynek csak 6 felhasználható kivezetése van, és 6 kbyte programmemóriája, valamint 512 byte ram-ja, már nem ennyire egyszerű a használat. Erről a leírás végén olvashatsz, he esetleg ilyen alaplappal is találkozni fogsz! De egyenlőre maradjunk az Arduino UNO használata mellett!

Így nézhet ki az Arduino és az I2C illesztővel egybeépített LCD kijelző hardveres összekötése:

Az LCD-re az I2C illesztő egységet simán csak rá kell dugni a gyárilag előre kialakított furatokra, és beforrasztani. Ehhez persze kell egy kis forrasztási tapasztalat, de nem nagy ördöngösség. Valahogy így néz ki a két panel összeforrasztva a szemben álló lukakat és tüskéket:

Ha nem szeretnél forrasztani, akkor olyan LCD kijelzőt keress, amit már eleve összeépítetek és beforrasztották az I2C illesztő áramkört az LCD kijelző modulra.
Az interneten számtalan program könyvtár található annak érdekében, hogy ne kelljen sokat programoznunk, és kényelmesen használhassuk a kijelzőnket. Én ezt a könyvtár telepítést még 2016-ban csináltam, és akkor I2C busszal működő programcsomagot nem találtam az Arduino könyvtár kezelő funkciójában. Nyugodtan keress magadnak ott egy megfelelő programcsomagot. Megmutatom, hogy hol keress, de én nem innen telepítettem magamnak programokat. Indítsd el az Arduino IDE programot és a könyvtár kezelés menü pontban keress:

Amit fentebb látsz a képen az éppen nem jó, mert nem I2C buszos illesztőn keresztül vezérli az LCD kijelzőt. Mivel én a kezdetek kezdetén nem találtam megfelelő programot a fentebb mutatott könyvtár kezelőben, a neten kerestem programcsomagot a Github-on. Találtam is. Ezt a program csomagot viszont másként kellett telepíteni. Itt találtam meg: https://github.com/fmalpartida/New-LiquidCrystal. Erről az oldalról egy ZIP tömörített állomány lehet letölteni. Jelenleg is letöltheted a programcsomagokat ilyen formában, csak kényelmesebb a könyvtárkezelő menüpontból. Ha netán egyszer majd arra kényszerülsz, hogy ZIP állományból kell telepítened programcsomagot, akkor a következőt kell tenned! Keresd meg az Arduino IDE-ben a következő menüpontot:

Tallózd ki a gépedről a letöltött ZIP állományt (valószínűleg a “Letöltések” mappában találod), és várj néhány másodpercet! Ezzel készen is vagy. Az Arduino IDE csinált a “Felhasználók\libraries” mappában a programcsomagnak egy alkönyvtárat, ide kibontotta a ZIP állomány tartalmát, és készen is vagyunk. Ez a programcsomag tartalmaz példa programokat, amiket megtalálsz az Arduino IDE Fájl menüjében a példák között. Én a NewLiquidCrystal.zip nevű állományt találtam meg akkor, és azóta is jól működik, minden programom ezt használja, amit a weblapon találsz.

Sajnos a programkönyvtárhoz kapott mintapéldák nem túl jók, de használd nyugodtan azt a programot a megismeréshez, amit ebben a leírásban találsz. Szinte minden funkciót beleraktam. Töredékét szoktam használni! Lehet nézegetni, de néhány alapvető infót megadnék.

A programban meg kell adnunk az I2C buszon az eszköz címét. Ez alapértelmezetten 0x27 a 16×2 méretű kijelzőnél. (Vettem magamnak 20×4 méretű kijelzőt is, annak gyárilag a 0x3F cím lett beállítva.) Ha azonban több kijelzőt is szeretnénk egyszerre csatlakoztatni, szükséges az egyes kijelzők (illetve a kijelzőket illesztő I2C panel) címeinek megkülönböztetésére. Ehhez az illesztő áramkör címeit három db rövidzár beforrasztásával, vagy éppen a forrasztás leszedésével tudjuk változtatni. A képen láthatók a panelen kialakított rövidzárak, mellette pedig a táblázat, hogy mely címekhez mely rövidzárat kell használni a háromból:

A kijelzőkbe bele építették a karakter generátort, ami azt jelenti, hogy nekünk csak karakter ASCII kódjait kell küldenünk a kijelzőnek, és a kijelző már tudja, melyik karakter hogy néz ki, és melyik pontot kell aktívvá tenni a karakter pontmátrixban ahhoz, hogy szemünk el tudja olvasni a megjelenő betűt vagy számot. A megjelenő karakterek ASCII kódjaihoz itt egy jól használható táblázat:

Ha az adott karakter ASCII kódjára vagy kíváncsi, az oszlop legfelső karakterének kódja az oszlop feletti szám, ettől kezdve számolj lefelé a neked szükséges karakterig soronként! Pl. a nagy “A” betű kódja 65.
Lehetőség van magyar ékezetes betűk használatára is. Ez azonban meglehetősen körülményes, mert a kijelző memóriájába kell feltölteni a karakter képeket, és egy külön utasítással lehet megjeleníteni a megfelelő karakter pozícióban. Így egy ékezetes magyar szó, csak több részletben írható ki. Természetesen ez nem katasztrofális hátrány, a teljesen kész és átgondolt szöveget érdemes utolsó lépésként ékezetesíteni. A magyar ékezetes karakterek képét a 0-7 kódokra lehet feltölteni, ami azt jelenti, hogy ha pl. a 2-es kódra töltöd fel az “á” betű képét, akkor az “A” betű a 65-ös ASCII kódra jelenik meg, míg az “á” betű a 2-es ASCII kódra (amit küldesz a kijelzőnek)! Ez így nagyon macerás, de működik.
Íme egy felkommentezett mintaprogram. Az utasítások a kommentekkel együtt remélhetőleg érthetők lesznek. Két előre megírt program gyűjteményt kell a fordítónak megadnunk, amit majd a fordító programunkhoz fog adni. Ezek a függvény könyvtárak az #include <> utasítással kerülnek beillesztésre.

#include <Wire.h>                              //I2C library
#include <LiquidCrystal_I2C.h>        //I2C LCD kezelő könyvtár
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  //LCD paraméterek megadása
void setup() 
{
  lcd.begin(16,2);                    //LCD inicializálása
  lcd.backlight();                    //háttérvilágítás bekapcsolása
  lcd.setCursor(0,0);                 //LCD kurzor a 1. sor 1. karakter pozícióba
  lcd.print("Hello!");                //Hello felirat a kurzortól kezdve
  lcd.setCursor(5,1);                 //LCD kurzor a 2. sor 6. karakter pozicióba
  lcd.print("Szia!");                 //Szia felirat a kurzortól kezdve
  delay(3000);                        //3 másodperc várakozás
  lcd.clear();                        //kijelző törlése
   for (byte i=0; i<16; i++) {
    lcd.setCursor(i,1);               //LCD kurzor a 2. sor i. pozicióba
    lcd.print("#");                   //a kurzor pozicióba egy "#"-jel beírása
    delay(100);
  }
  for (byte i=0; i<16; i++) {
    lcd.setCursor(i,1);               //LCD kurzor a 2. sor i. pozicióba
    lcd.print(" ");                   //a kurzor pozició karakterének letörlése egy szóközzel.
    delay(100);
  }
  //egyéb kijelző kezelő függvények bemutatása 
  //háttérvilágítás ki és bekapcsolása
  lcd.clear();lcd.println("Hatter vilagitas");lcd.setCursor(0,1);lcd.print("kikapcsolas");
  delay(3000);lcd.noBacklight();delay(3000);lcd.backlight();delay(3000);
  //Cursor pozició villogtatása sötét hátérrel.
  lcd.clear();lcd.print("Blink funkcio"); lcd.blink(); delay(3000);lcd.noBlink();
  //Bekapcsoljuk a blink funkciót és a szöveg kiírását követően balra mozdítjuk a kurzort
  lcd.clear();lcd.blink();lcd.print("Cursor balra");delay(3000);lcd.moveCursorLeft();delay(3000);lcd.noBlink();
  //Bekapcsoljuk a blink funkciót és a szöveg kiírását követően jobbra mozdítjuk a kurzort
  lcd.clear();lcd.blink();lcd.print("Cursor jobbra");delay(3000);lcd.moveCursorRight();delay(3000);lcd.noBlink();
  //szöveg kiírást követően bekapcsoljuk a kurzort, majd kis idő mulva kikapcsoljuk
  lcd.clear();lcd.print("Cursor on");delay(3000);lcd.cursor();delay(3000);
  lcd.clear();lcd.print("Cursor off");delay(3000);lcd.noCursor();delay(3000);
  //kikapcsoljuk a display-t. A vikágítás marad, de szövegek nem láthatóak, azonban a tartalom nem törlődik, bekapcsoláskor ujra láthatóvá válik
  lcd.clear();lcd.print("Disp. ki es be!");lcd.setCursor(0,1);lcd.print("Vilagitas marad!");delay(3000);
  lcd.noDisplay();delay(3000);lcd.display();delay(3000);
  //kikapcsoljuk a display-t. Teljes kikapcsiolás, a világítás is lekapcsolódik. A tartalmat azonban nem felejti el, visszakapcsoláskor ujra láthatóvá válik az előzőleg kiírt szöveg
  lcd.clear();delay(3000);lcd.print("Disp. teljes ki");lcd.setCursor(0,1);lcd.print("es bakapcsolasa");delay(3000);
  lcd.off();delay(3000);lcd.on();delay(3000);
  //A kiírt szöveget balra mozdítjuk egy pozicióval
  lcd.clear();lcd.print(" Scroll balra");delay(3000);lcd.scrollDisplayLeft();delay(3000);
  //A kiírt szöveget jobbra mozditjuk egy pozicióval
  lcd.clear();lcd.print("Scroll jobbra");delay(3000);lcd.scrollDisplayRight();delay(3000);
  //kiírjuk az "Autoscroll:" szöveget és bekapcsoljuk az autoscroll funkciót. Kiírunk 10 számot,
  //és az eredetileg kiírt szöveg balra tolódik egy egy pozicióval a számok kiírásakor
  lcd.clear();  lcd.print("Autoscroll:");delay(3000);
  lcd.autoscroll();for (int i=0; i<10; i++) {lcd.print(i);delay(200);}lcd.noAutoscroll();
  //bekapcsoljuk a jobbra írás funkciót, és a write függvénnyel kiírunk egy szöveget
  lcd.clear();lcd.leftToRight(); lcd.write("Jobbra irt szov.");delay(3000);
  //balra írás mód
  lcd.clear();lcd.setCursor(15,0);lcd.rightToLeft();lcd.write("Balra irt szoveg");delay(3000);lcd.leftToRight();
  //Magyar éklezetes kisbetűk használata
  //ékezetes betűk karakterképének definiciója tömbökben. Csak nyolc saját karakterünk lehet, ebből 7-et kell felhasználnunk
  byte aI_t[8] = {B10,B100,B1110,B1,B1111,B10001,B1111};             //á betű karakterképe
  byte eI_t[8] = {B10,B100,B1110,B10001,B11111,B10000,B1110};   //é betű karakterképe
  byte iI_t[8] = {B10,B100,B0,B1110,B100,B100,B1110};                     //í betű karekterképe
  byte oI_t[8] = {B10,B100,B0,B1110,B10001,B10001,B1110};            //ó betű karakterképe
  byte uI_t[8] = {B10,B100,B10001,B10001,B10001,B10011,B1101}; //ú betű karakterképe
  byte oII_t[8] = {B00101,B01010,B0,B1110,B10001,B10001,B1110};    //ő betű karakterképe
  byte uII_t[8] = {B00101,B01010,B0,B10001,B10001,B10011,B1101};  //ű betű karakterképe
  //Az ö 239, az ü 245 ascii kódon megtalálható akarakterek között, azt nem kell definiálni
  //saját kerakterek betöltése a kijelző memóriájába
  lcd.createChar(0, aI_t);lcd.createChar(1, eI_t);lcd.createChar(2, iI_t);lcd.createChar(3, oI_t);
  lcd.createChar(4, uI_t);lcd.createChar(5, oII_t);lcd.createChar(6, uII_t);
  //Csak azért, hogy könnyebb legyen az ékezetes karaktereket kiírni, beszédesebb nevű változókba
  //töltöm azt a kódot, amit a kijelzőnek kell küldeni a karakter megjelenítéséhez
  byte aI=0;byte eI=1;byte iI=2;byte oI=3;byte uI=4;byte ooo=239;byte uoo=245;byte oII=5;byte uII=6;
  lcd.clear();
  //ékezetes karakterek kiírása a kijelzőre
  lcd.write(eI);lcd.print("kezetes bet");lcd.write(uII);lcd.print("k:");
  lcd.setCursor(7,1);
  lcd.write(aI);lcd.write(eI);lcd.write(iI);lcd.write(oI);lcd.write(uI);lcd.write(239);
  lcd.write(245);lcd.write(oII);lcd.write(uII);
}
void loop()
{
}

Ha esetleg valakinek egy 4 sor 20 karakteres kijelzőt sikerülne beszerezni, annak gondolnia kell arra, hogy a kijelző I2C címe 3F, így a programban ezt kell írni a harmadik sorba:
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Egyébként a 4 soros kijelző minden gond és változtatás nélkül működik, csak több infó fér el rajta. Kicsit drágább is, h jól emlékszem 1200Ft körül lehet beszerezni.


Két kijelző használata:

Nincs pillanatnyilag két kijelzőm, ezért az alábbi programot nem próbáltam ki. Azonban más moduloknál mindig jól működött.
Szerintem első lépésben külön címet kell beforrasztani a kijelzőkön, és a programban a következőket kell írni:

#include <Wire.h>                              //I2C library
#include <LiquidCrystal_I2C.h>        //I2C LCD kezelő könyvtár
LiquidCrystal_I2C lcd1(0x26, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  //egyik LCD paramétereinek megadása
LiquidCrystal_I2C lcd2(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  //másik LCD paramétereinek megadása

Itt talán látható, hogy más-más változó nevet adtam a két kijelzőnek. Így már külön-külön lehet rájuk hivatkozni a programban. pl.:

 lcd1.begin(16,2);                  //LCD1 inicializálása
 lcd1.backlight();                  //háttérvilágítás bekapcsolása
 lcd1.setCursor(0,0);               //LCD1 kurzor a 1. sor 1. karakter pozícióba
 lcd1.print("Hello!");              //Hello felirat a kurzortól kezdve

 lcd2.begin(16,2);                   //LCD2 inicializálása
 lcd2.backlight();                   //háttérvilágítás bekapcsolása
 lcd2.setCursor(0,0);                //LCD2 kurzor a 1. sor 1. karakter pozícióba
 lcd2.print("Hello!");               //Hello felirat a kurzortól kezdve

Ékezetes betűk írása nagyon nehézkes a programban, ezért csináltam egy általános függvényt, ami ezt kényelmesebbé teszi. Esetleg nézd meg ezt is!

Sőt! Kis idő elteltével további változó típusokra is csináltam univerzális megjelenítő függvényt. Így kényelmesen lehet dátumokat, időpontokat és számadatokat írni a kijelzőre. Kezdőknek talán azért is érdemes megnézni ezt a programot, mert néhány érdekesség kiderül a változók kezeléséről, valamint arról, hogyan lehet C++-ban ugyanazt a függvényt több példányban is elkészíteni, egy programon belül, és mi ennek az értelme!

ATtiny85 modul és az LCD karakteres kijelző

Mielőtt ezt a leírás részt elolvasod, érdemes megismerkedni az ATtiny85 modullal, mert ahhoz, hogy programot tudj rátölteni, még le kell töltened egy alaplap kezelő könyvtárat, mert az Arduino IDE alap helyzetben nem tudja kezelni. Valamint kell egy drivert is telepíteni a Windows 10-hez. Ennek részletes leírása itt!

Az a gond az ATtiny85 chip-el, és persze a belőle készített modullal, hogy nagyon kicsi a program meória (8 illetve 6 kbyte), és nagyon kicsi a ram (512 byte). A szokásos könyvtárak ezért nem tudnak működni, mert nem férnek el a memóriában. Amikor erről olvasgattam, úgy tűnt, más apróbb különbségek is vannak a hardverben, ami miatt módostani kell a kezelő programokon, de ezekkel nem foglalkoztam részletesen, mert nem érdekeltek. Az biztos, hogy új, sokkal kisebb méretű kezelő programok kellenek, feltehetőleg szerényebb funkcionalitással, vagy sokkal optimálisabban megírt forráskóddal. Egy I2C LCD kijelzőhöz két dolog kell, a Wire könyvtár ami az I2C buszt kezeli, és egy LCD kijelző programkönyvtár. Mindkettő létezik ATtiny85-re, és az a jó hírem, hogy ha telepítetted at ATtiny85 alaplapkezelő könyvtárat, akkor már a gépeden is van mindkettő, csak használni kell.

Íme a működésre bírható példa program:

#include <TinyWireM.h>                  // I2C könyvtár ATtiny85-höz
#include <LiquidCrystal_I2C.h>          // LCD könyvtár ATtiny85-höz
LiquidCrystal_I2C lcd(0x3F,20,4);       // kijelző I2C címének és méretének beállítása


void setup(){
  TinyWireM.begin();                    // I2C inicializálása
  lcd.init();                           // LCD inicializálása
  lcd.backlight();                      // Háttérvilágítás bekapcsolása
  lcd.setCursor(0,0);                   // kezdő pozíció (0. karakter a 0. sorban)
  lcd.print("Hello, Tiny85!");
  lcd.setCursor(0,1);
  lcd.print("Hello, LCD!");            // kezdő pozíció (0. karakter a 1. sorban)
}


void loop(){
}

Természetesen nekem nem sikerült lefordítani a programot. Kaptam egy hibaüzenetet:

Ebből a hibahalmazból nem volt nehéz kideríteni, hogy mi a baj! Fejlesztés közben elég sok programkönyvtárat kipróbálok, telepítgetem amit találok, de eddig soha nem szedtem le azt, amit már nem használok. Sajnos itt most ugyanazt a nevet két programkönyvtárban is megtalálta a fordító, és feltehetőleg azt kezdte el használni, amit először megtalált. Látható, hogy a TinyWireM is kétszer van meg (ezt nem is tudtam, hogy már régebben letöltöttem), de ezek valószínűleg azonosak, így nincs belőle baj. Viszont a „LiquidCrystal_I2C.h” benne van a NewliquidCristal nevű programkönyvtárban (erre emlékszem, szoktam használni), és a most letöltött alaplapkezelővel is kaptam egy ugyanilyen nevűt. Nincs mit tenni, a NewliquidCristal könyvtárat legalább erre az egy alkalomra meg kell szüntetni! Ez nagyon egyszerű, ehhez csak azt kell tudni, hogy az Arduino IDE a könyvtár kezelőben letöltött könyvtárakat alapértelmezetten (Windows10-ben) az adott felhasználó, dokumentumok könyvtára alatt létrehozott „Dokumentumok\Arduino\Libraries” alkönyvtárba helyezi telepítéskor. Elég innen elmásolni valahová a teljes alkönyvtárat! Én csináltam egy „Dokumentumok\Arduino\nem_használt_Libraries” alkönyvtárat, és oda másoltam. Előfordulhat, hogy régebbi programjaimban használtam valamikor és még szükség lesz rá. Bár valószínűleg azokat a programokat egyszerűbb lesz átalakítani ehhez a könyvtárhoz. Még az is lehet, hogy semmit nem kell csinálni, ezzel is működni fognak, de ezt előre nem lehet tudni biztosan.

Mindenesetre így már lefordul a program, és működik is! Feltöltéskor először ki kell húzni az USB-ből az alaplapot, és csak akkor bedugni, amikor szól a az Arduino IDE. Erről részletesebben itt olvashatsz!

Mennyire volt hasznos amit olvastál?

Kattints egy csillagra az értékeléshez!

Szövegesen is leírhatod véleményedet!