Tartalom:
- Adatkiírás formázott módon karakteres LCD kijelzőre
- Számadatok kiírása fix hosszúságban és rövid kiírással, tizedes jegyek számának megadásával
- Dátumok kiírása (magyar formátumban, évszázaddal, vagy anélkül, adott nap nevével vagy anélkül)
- Időpontok kiírása (12 órás vagy 24 órás formátumban másodpercekkel vagy anélkül
- Teljes forráskód, példa program
———————————————————————————————
Annyit kínlódtam már az LCD kijelzőre történő formázott kiírással, hogy elegem lett, és elhatároztam, hogy csinálok magamnak egy olyan általános függvényt, ami mentesít a rengeteg programonként ismétlődő formázási és ékezetesítési feladattól. Először csak az ékezetesítés „akasztott ki” és csináltam is ehhez egy külön függvényt. Persze evés közben jön meg az étvágy! Első lépésben meghatároztam, hogy milyen elvárásai lennének egy ilyen függvénnyel szemben:
- Magyar ékezetes szöveg írása
- Különféle típusú egész számok minimális hossz megadásával (szóközzel feltöltve, ha rövid a szám)
- Float típusú számadat, beállítható tizedesjegy számmal és minimális hossz megadásával
- 24 órás formátumú időpont kiírás másodpercekkel vagy azok nélkül
- 12 órás formátumú időpont kiírás másodpercekkel vagy azok nélkül
- Dátum kiírás évszázaddal vagy anélkül, hét napjának megnevezésével, vagy anélkül
Rögtön adtam egy nevet a leendő függvényemnek: lcd_uniprint()
Biztosan létezik hasonló kész függvénykönyvtár, találtam is, de egyik sem pont olyan volt, mint amire nekem szükségem lenne. Az alább részletezett függvény formázottan ír ki adatokat LCD kijelzőre. Remélem más is fel tudja használni valamire. Nagy előnye, hogy ott a forrás, ha valami nem kell belőle, ki lehet törölni, vagy ha valami másként kell, akkor át lehet alakítani. Egy kész könyvtárral szemben ez előny lehet.
Az LCD kijelzőt a programban a megszokott módon kell inicializálni, a kijelző hivatkozási neve kötelezően „lcd”. Ha más névre van szükség, akkor a függvényekben át kell írni az lcd.print() függvényben az előtagot. Két LCD kijelzőt nem kezel, ahhoz vagy a függvényeket kell megduplázni más néven, vagy új paramétert kell bevezetni, és belül kiválasztani a kijelzőt.
A forráskódban hat azonos nevű függvényt írtam meg a hat előző felsorolt elvárásnak megfelelően. A függvényeket a C++ annak megfelelően hívja meg, hogy milyen a megadott paraméterek adattípusa. Ebből a hat esetből 3 saját magam által létrehozott egyedi változó típus, 24 órás idő, 12 órás idő és dátum típusok. Ezekben a változó típusokban önkényesen határoztam meg a tag változók neveit. Ha időpontot vagy dátumot szeretnénk formázottan kiírni LCD kijelzőre, akkor ezeket a változókat struktúraként deklarálni kell a programban.
Nyilvánvaló, hogy a fennmaradó három változó típus kevesebb, mint amit C++-ban használhatunk. Ezek a függvények csak a String, Long és Float változó típusokra készültek el. Úgy gondoltam, hogy lényegében ezzel a három alaptípussal mindenféle információ megjeleníthető a kijelzőn. Így ha pl. egy Byte típusú változót szeretnénk megjeleníteni, arra nem írtam függvényt, tehát meg sem tudná hívni a rendszer a megfelelő függvényt. Ekkor a változó be kell írnunk zárójelben a szükséges típus nevét, és a C++ konvertálni fogja a változót a zárójelbe írt változó típusra, és így már megtalálja a neki megfelelő függvényt. Pl.: lcd_iniprint( (Long) 1000 ). A példában nem változót írtam, hanem direktben egy értéket, ahol eleve kérdéses, hogy a C++ milyen változónak értelmezné a megadott „1000” számot. Úgy emlékszem Int típus lenne belőle, de ez mindegy is, mert Long-lesz, és így megoldódott a probléma. A String típussal van némi probléma, mert ha a függvény meghívásakor direkteben „..” jelek közé írt szöveget adok meg paraméterként, azt valamilyen rejtélyes okból a C++ nem Stringnek tekinti, hanem karakter tömbnek, és az első tömbelem típusának megfelelő függvényt hívna meg. Így, ha szöveget akarunk megjeleníteni, akkor elé kell írni zárójelben „(String)”, és csak így működik jól a program. Pl.: lcd_uniprint( (String) „Szöveg”). Ha ugyanekkor egy String típusú változót adunk meg, akkor jól működik. Amennyiben tizedes jegyeket is meg kell jelenítenünk, a Float típusra kell konvertálni.
Az egyes függvények működése és paramétereik használata néhány mondatban összefoglalva:
lcd_uniprint(String) magyar ékezeteket tartalmazó szöveg ékezetes kiírása
Ez a függvény képes feltölteni a magyar ékezetes betűk (csak kis betűk, mert többre nincs memória hely) karakterképét az LCD kijelzőre, ha üres String paraméterrel hívjuk meg. Ha a paraméter nem egy üres string, akkor megkeresi az ékezetes betűket (2 byte-on kerülnek a stringbe), eltávolítja az egyik felesleges byte-ot, a másikat pedig arra a kódra cseréli, amit a kijelzőnek kell küldeni az adott user karakter megjelenítéséhez (0-7 kódok).
lcd_uniprint( (String) szöveg);
- Paraméter egy tetszőlegesen ékezetes betűket is tartalmazó String típusú változó, vagy szöveg „..” között. Sajnos, ha idézőjelek között direktben adjuk meg a stringet, akkor azt nem String-nek tekinti, és rossz függvény változatot hív meg, ezért konvertálni kell a (String) konverzióval, amit az időzőjelekkel megadott string elé kell beírni. Ha String típusú változót adunk meg paraméterként, akkor rendesen működik
lc_uniprint(Long,Byte) egész számok kiírására
Ez a függvény akkor hívódik meg, ha az első paraméter Long típusú és még egy Byte típusú paraméter lett megadva. A megkapott Long típusú számot a Byte típusú változóval megadott minimális hosszban megadott karakterszámon írja ki. Ha a második paraméter nulla, akkor a számjegyek igényelt hosszának megfelelő helyet fog foglalni. Ha a számjegyek száma nagyobb, mint a megadott minimum, akkor hosszabb helyet fog elfoglalni a kiíráskor a megadott szám.
lcd_uniprint( (long) szám, minimális hossz);
- Első paraméter egy numerikus adatot tartalmazó változó, amely Bool, Byte, Int, Unsigned Int, Short stb. lehet, mert a zárójelbe írt (long) ezt Long típussá konvertálja, így a függvény Long típussal hívódik meg. A Long típus a leghosszabb egész, így elegendő volt csak erre megírni az lcd_uniprint() függvényt.
- Második paraméter a kiírt szám minimális hossza. Ha értéke 0, akkor pont annyi karakteren íródik ki, amennyire szükség van. Ha 0-nál nagyobb, akkor minimum annyi karakter helyet foglalunk a számnak, amennyit itt megadtunk. pl. ha 4, akkor egyjegyű szám elé 3 szóközt tesz, kétjegyű elé csak két szóközt stb. Ha a kiírásra kerülő szám jegyeinek száma nagyobb, mint amennyit megadtunk, akkor több karaktert fog a kiíráskor elfoglalni. Ha azonban tudjuk a kiírásra kerülő szám maximális hosszát, úgy lehet kiírni, hogy nem változik a számot követő egyéb adatok pozíciója, nem ugrál a szöveg stb.
lcd_uniprint(float, Byte, Byte) tizedes jegyeket tartalmazó szám kiírására
Ez a függvény akkor hívódik meg, ha az első paraméter Float típusú és még két Byte típusú paraméter lett megadva. A megkapott Float típusú számot az első paraméterben megadott karakterszám hosszban írja ki, ha ez a paraméter nulla, akkor a számjegyek igényelt hosszának megfelelő helyet fog foglalni. Ha a számjegyek száma nagyobb, mint a megadott minimum, akkor hosszabb helyet fog elfoglalni a kiíráskor a megadott szám. A tizedes jegyek száma a harmadik paraméterrel állítható be
lcd_uniprint( (float) szám, minimális hossz, tizedesek száma);
- Az első paraméter egy Float típusú, tizedes jegyeket tartalmazó szám. Amennyiben nem Float típusú, akkor elé kell írni (float), hogy mindenképpen Float legyen különben nem tudja meghívni ezt a függvény változatot.
- Második paraméter a megjelenített szám minimális hossza a tizedesjegyekkel és a tizedesponttal együtt. Ha nem kell tizedespont, akkor (long)-ot kell elé írni és az előző függvényváltozat fogja kiírni az adatot. Ha a számadat hosszabb, mint ez a megadott érték, akkor a kiírt adat is több helyet igényel. Ha a minimális hossz értéke 0, akkor pont annyi helyre fogja kiírni a számot, amennyit igényel.
- Harmadik paraméter a tizedesjegyek száma.
lcd_uniprint(time_24, bool) 24 órás formátumú időpont kiírása másodpercekkel vagy anélkül
Ez a függvény megkap egy időpontot, amit 24 órás időpontnak feltételez. Az óra, perc és másodperc értékét is megformázza oly módon, hogy mindig két karakter hosszú legyen, így az időpont kiírása fix hosszúságú, pl.: „00:00:00”. Az óra, perc és másoderc értékeket ellenőrzi, és a kisebb és anagyobb értékeket minimumra (0-ra) illetve maximumra (23,59) helyettesíti. A time_24 típusú változót várja első paraméterként, ennek változó tag nevei:
ora – a 24 órás időpont óra értéke
perc– a perc értéke
masodperc – a másodperc értéke
A második paraméter megszabja, hogy kérjük-e a másodperc kiírását. Ha értéke 0, akkor nem ír másodpercet, csak az órát és perceket, ha értéke 1, akkor a teljes időpontot írja ki „óra:perc:masodperc” formában!
lcd_uniprint(time_24 típusú változó, másodperc megjelenítés)
- Első paraméter egy time_24 nevű struktúrában létrehozott változó (ora, perc, masodperc tag változó nevekkel)
- második paraméter jelzi, hogy kell-e a másodperceket megjeleníteni (0-nem kell, 1-kell)
lcd_uniprint(time_12,bool) 12 órás formátumú időpont kiírása másodpercekkel vagy anélkül „am” illetve „pm” jelzéssel az időpont előtt
Ez a függvény megkap egy időpontot, amit 12 órás időpontnak feltételez és „am” illetve „pm” jelzéssel látja el a kiírt időt. Az óra, perc és másodperc értékét is megformázza oly módon, hogy mindig két karakter hosszú legyen, így az időpont kiírása fix hosszúságú pl.: „am/pm 00:00:00”
Az óra, perc és másoderc értékeket ellenőrzi, és a kisebb és a nagyobb értékeket minimumra (0-ra) illetve maximumra (12,59) helyettesíti. A time_12 típusú változót várja első paraméterként, ennek változó nevei:
ora – a 12 órás időpont óra értéke
perc – a perc értéke
masodperc – a másodperc értéke
pm_am – ha értéke 0, akkor délelőtt, ha 1 akkor délután
A második paraméter megszabja, hogy kérjük-e a másodperc kiírását. Ha értéke 0, akkor nem ír másodpercet, csak az órát és perceket, ha értéke 1, akkor a teljes időpontot írja ki „óra:perc:masodperc” formában.
lcd_uniprint(time_12 típusú változó, másodperc megjelenítés)
- első paraméter egy alább található time_12 nevű strukturában létrehozott változó (ora, perc, masodperc, pm_am változó nevekkel)
- második paraméter jelzi, hogy kell-e a másodperceket megjeleníteni (0-nem kell, 1-kell) az időponthoz „am” illetve „pm” feliratokat tesz hozzá egy szóközzel elválasztva
lcd_uniprint(datum, bool, bool) dátum kiírása évszázaddal vagy anélkül, hétnapjának szöveges kiírásával vagy anélkül
Ez a függvény megkap egy dátumot, és formázottan kiírja az LCD kijelzőre. Beállítható, hogy az évszázadot is kiírja, vagy csak az év utolsó két jegyét. Beállítható, hogy a hét napját szövegesen is kiírja a dátum érték után. A dátum kiírása fix hosszúságú: pl.: „2021.10.01” vagy „21.10.01” Az év, hó és nap értékeket ellenőrzi, és kisebb nagyobb értékeket minimumra (0-ra) illetve maximumra (12,31,9999) helyettesíti. Nem ellenőrzi a dátum helyességét és a hét napjának egyezőségét, tehát elfogadja februárt 31 naposnak, és nem szól, ha egy nap péntek, valójában dátum szerint szombat. A datum típusú változót várja első paraméterként, ennek változó nevei:
ev – az evszam
ho – a hónap
nap – a nap
hetnapja – a hét napja, 1 hétfő….7 vasárnap
A második paraméter azt adja meg, hogy kell-e kiírni szövegesen a hét napját. Ha értéke 0, akkor nem kell kiírni, ha értéke 1, akkor a dátum mögé kiírja szövegesen. A leghosszabb szöveges kiírás a „csütörtök”, ez összesen +10 karakter, 16 karakteres LCD-n már nem fér ki. A harmadik paraméter megszabja, hogy kérjük-e az évszázad kiírását. Ha értéke 0, akkor nem ír évszázadot pl. „21.10.01” ha értéke 1, akkor kiírja az évszázadot pl. „2021.10.01”
lcd_uniprint(datum típusú változó, hét napjának kijelzése, évszázad kijelzése)
- Első paraméter egy datum nevű strukturában létrehozott változó (ev, ho, nap, hetnapja változó nevekkel)
- Második paraméter jelzi, hogy kell-e a hét napját szövegesen kiírni (0-nem kell, 1-kell). A datum mögé írja szóközzel elválasztva, ha kell!
- Harmadik paraméter jelzi, hogy évszázadot ki kell-e írni (0-nem kell pl 21 (2021 esetén), 1- kell pl. 2021)
Ellenőrzések:
- Ha a megadott év kisebb mint 0, akkor 0-val helyettesíti, ha nagyobb mint 9999, akkor 9999-el helyettesíti
- Ha a megadott hónap 1-nél kisebb, akkor 1-el helyettesíti, ha nagyobb mint 12, akkor 12-el helyettesíti
- Ha a megadott nap 1-nél kisebb, akkor 1-el helyettesíti, ha nagyobb mint 31, akkor 31-el helyettesíti (hónap napjainak számát nem ellenőrzi)
- Ha a megadott hét napja 1-nél kisebb, akkor 1-el helyettesíti (hétfő), ha nagyobb mint 7, akkor 7-el helyettesíti (dátum és hét napja egyezőségét nem ellenőrzi)
…és végül a forrás sok-sok mintapéldával, hogy értehető legyen, amint fentebb leírtam:
/************************************************************************************************************************************************************************** * lcd_uniprint() függvény: * * Az alább részletezett függvény formázottan ír ki adatok lcd kijelzőre. Az lcd kijelzőt a programban a megszokott módon kell inicializálni, a kijelző hivatkozási * * neve kötelezően "lcd". Ha más névre van szükség, akkor a legutolsó függvény változatban át kell írni az lcd.print() függvényben az előtagot. * * Két LCD kijelzőt nem kezel, ahhoz vagy a függvényeket kell megduplázni más néven, vagy új paramétert kell bevezetni, és belül kiválasztani a kijelzőt. * * * * Ékezetes szöveg írása LCD kijelzőre: lcd_uniprint( (String) szöveg); * * - Paraméter egy tetszőlegesen ékezetes betűket is tartalmazó string típusú változó, vagy szöveg "" között * * Sajnos ha idézőjelek között direktben adjuk meg a stringet, akkor azt nem String-nek tekinti, és rossz függvény változatot hív meg, ezért konvertálni kell * * a (String) konverzióval, amit az időzőjelekkel megadott string elé kell beírni. Ha string típusú változót adunk meg paraméterként, akkor rendesen működik * * * * Különféle típusú egész értékű numerikus adatok formázottok kiírása minimális hosszal: lcd_uniprint( (long) szám, minimális hossz); * * - Első paraméter egy numerikus adatot tartalmazó változó, amely bool, byte, int, unsigbned int, short stb. lehet, mert a zárójelbe írt (long) ezt long típussá * * konvertálja, így a függvény long típussal hívódik meg. A long típus a leghosszabb egész, így elegendő volt csak erre megírni az lcd_uniprint() függvényt. * * - Második paraméter a kiírt szám minimális hossza. Ha értéke 0, akkor pont annyi karakteren íródik ki, amennyire szükség van. Ha 0-nál nagyobb, akkor * * minimum annyi karakter helyet foglalunk a számnak, amennyit itt megadtunk. pl. ha 4, akkor egyjegyű szám elé 3 szóközt tesz, kétjegyű elé csak két szóközt stb. * * Ha a kiírásra kerülő szám jegyeinek száma nagyobb mint amennyit megadtunk, akkor több karaktert fog a kiíráskor elfoglalni. Ha azonban tudjuk a kiírásra kerülő * * szám maximális hosszát, úgy lehet kiírni, hogy nem változik a számot követő egyéb adatok poziciója, nem ugrál a szöveg stb. * * * * Float típusú számadat, beállítható tizedesjegy számmal és minimális hosszal: lcd_uniprint( (float) szám, minimális hossz, tizedesek száma); * * - Az első paraméter egy float típusú, tizedes jegyeket tartalmazó szám. Amennyiben nem float típusú, akkor elé kell írni (float), hogy mindenképpen float legyen * * különben nem tudja meghívni a hozzá tartozó lcd_uniprint() függvényt meghívni, ami float típusú paramétert vár. * * - Második paraméter a megjelenített szám minimális hossza a tizedesjegyekkel és a tizedesponttal együtt. Ha nem kell tizedespont, akkor (long)-ot kell elé írni * * és az előző függvényváltozat fogja kiírni az adatot. Ha a számadat hosszabb mint ez a megadott érték, akkor a kiírt adat is több helyet igényel. * * Ha a minimális hossz értéke 0, akkor pont annyi helyre fogja kiírni a számot, amennyit igényel. * * - harmadik paraméter a tizedesjegyek száma. * * * * 24 órás formátumú időpont kiírás másodpercekkel vagy azok nélkül: lcd_uniprint(time_24 típusú változó, másodperc megjelenítés) * * paraméter egy alább található time_24 nevű strukturában létrehozott változó (ora, perc, masodperc változó nevekkel) * * második paraméter jelzi, hogy kell-e a másodperceket megjeleníteni (0-nem kell, 1-kell) * * * * 12 órás formátumú időpont kiírás másodpercekkel vagy azok nélkül: lcd_uniprint(time_12 típusú változó, másodprec megjelenítés) * * első paraméter egy alább található time_12 nevű strukturában létrehozott változó (ora, perc, masodperc, pm_am változó nevekkel) * * második paraméter jelzi, hogy kell-e a másodperceket megjeleníteni (0-nem kell, 1-kell) * * az időponthoz "am" illetve "pm" feliratokat tesz hozzá egy szóközzel elválasztva * * * * Dátum kiírás évszázaddal vagy anélkül, hét napjának megnevezésével, vagy anélkül:lcd_uniprint(datum típusú változó, hét napjának kijelzése, évszázad kijelzése) * * - Első paraméter egy alább található datum nevű strukturában létrehozott változó (ev, ho, nap, hetnapja változó nevekkel) * * - Második paraméter jelzi, hogy kell-e hét napját szövegesen kiírni (0-nem kell, 1-kell). A datum mögé írja szóközzel elválasztva, ha kell! * * - Harmadik paraméter jelzi, hogy évszázadot ki kell-e írni (0-nem kell pl 21 (2021 esetén), 1- kell pl. 2021) * * Ellenőrzések: * * - Ha a megadott év kisebb mint 0, akkor 0-val helyettesíti, ha nagyobb mint 9999, akkor 9999-el helyettesíti * * - Ha a megadott hónap 1-nél kisebb, akkor 1-el helyettesíti, ha nagyobb mint 12, akkor 12-el helyettesíti * * - Ha a megadott nap 1-nél kisebb, akkor 1-el helyettesíti, ha nagyobb mint 31, akkor 31-el helyettesíti (hónap napjainak számát nem ellenőrzi) * * - Ha a megadott hét napja 1-nél kisebb, akkor 1-el helyettesíti (hétfő), ha nagyobb mint 7, akkor 7-el helyettesíti (dátum és hét napja egyezőségét nem ellenőrzi) * **************************************************************************************************************************************************************************/ #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, ez most 2x16 karakteres kijelző //SimulIde áramkör szimulátorban nincs csak szoftveres I2C LCD könyvtár, ha ott akarom futtatni a programot, //akkor a fenti két sort kell kikommentezni, és az it következő öt sort tenni helyette //#include <Soft_LCD-I2C.h> //uint8_t address = 80; //uint8_t sda = 18; //uint8_t scl = 19; //Soft_Lcd_I2C lcd( address, 16, 2, sda, scl ); struct time_24 { //24 órás időpont tárolására alkalmas változó struktúra létrehozása, ezt követően lehetnek time_24 saját típusú változóink byte ora; //Csak akkor van szükség ennek a struktúrának a deklarálására, ha 24 órás időpontot akarunk kiírni, egyébként törölhető byte perc; //a hozzá tartozó lcd_uniprint() függvénnyel együtt, amelyben a bementő paraméter time_24 típusú byte masodperc; }; struct time_12 { //12 órás időpont tárolására alkalmas változó struktúra létrehozása, ezt követően lehetnek time_12 saját típusú változóink byte ora; //abban különbözik a 24 órás változattól, hogy meg kell adni, hogy a megadott időpont délelőtt, vagy délután. byte perc; //Csak akkor van szükség ennek a struktúrának a deklarálására, ha 12 órás időpontot akarunk kiírni, egyébként törölhető byte masodperc; //a hozzá tartozó lcd_uniprint() függvénnyel együtt, amelyben a bementő paraméter time_12 típusú bool pm_am; }; struct datum { //dátum tárolására alkalmas változó struktúra létrehozása, ezt követően lehetnek datum saját típusú változóink int ev; //Csak akkor van szükség ennek a struktúrának a deklarálására, ha dátumot akarunk kiírni, egyébként törölhető byte ho; //a hozzá tartozó lcd_uniprint() függvénnyel együtt, amelyben a bementő paraméter datum típusú byte nap; byte hetnapja; }; void setup() { Serial.begin(9600); //csak fejlesztéshez használva, ha kell soros port lcd.begin(16,2); //LCD inicializálása lcd.clear(); //LCD törlés lcd.backlight(); //háttérvilágítás bekapcsolása lcd_uniprint((String)""); //üres stringgel hívtam meg a függvényt, ez jelenti, hogy töltse fel a magyar karakterképeket //ha használni akarjuk a függvényt, ezt egyszer az első használat előtt meg kell tenni. lcd.setCursor(0,0);lcd_uniprint((String)"Nagy:ÁÉÍÓÖŐÚÜŰ"); //összes nagy ékezetes betű írása (mind kicsiként fog megjelenni) lcd.setCursor(0,1);lcd_uniprint((String)"Kicsi:áéíóöőúüű"); //összes kis ékezetes betű írása delay(2000); //2 másodperc várakozás bool bool_ertek_l=LOW; //létrehozunk egy bool típusú változót, és adunk neki értéket bool bool_ertek_h=HIGH; //létrehozunk egy másik bool típusú változót, és adunk neki értéket lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Bool érték:"); lcd.setCursor(0,1);lcd_uniprint((String)"High:"); lcd_uniprint((long)bool_ertek_h,1); //bool változó tartalmának kiírása egy karakter hosszban lcd.setCursor(8,1);lcd_uniprint((String)"Low:"); lcd_uniprint((long)bool_ertek_l,2); //bool változó tartalmának kiírása minimum két karakterhosszban delay(2000); byte byte_ertek=250; //létrehozunk egy byte típusú változót, és adunk neki értéket lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Byte érték:"); lcd.setCursor(0,1);lcd_uniprint((long)byte_ertek,5); //byte változó tartalmának kiírása 5 karakter hosszban delay(2000); int int_ertek_plusz=16534; //létrehozunk egy int típusú változót, és adunk neki pozítív értéket int int_ertek_minusz=-16534; //létrehozunk egy int típusú változót, és adunk neki negatív értéket lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Int értek:"); lcd.setCursor(0,1);lcd_uniprint((long)int_ertek_plusz,3); //int változó tartalmának kiírása 3 karakterhosszban (annyin írja ki, amannyi kell, azaz 5 hosszban) lcd.setCursor(8,1);lcd_uniprint((String)"="); lcd_uniprint(int_ertek_minusz,0); //int változó tartalmának kiírása annyi helyre, amennyit igényel delay(2000); long long_ertek_plusz=2147483647; //létrehozunk egy long típusú változót, és adunk neki pozítív értéket maximum 2,147,483,647 lehet lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Long érték:"); lcd.setCursor(0,1);lcd_uniprint((long)long_ertek_plusz,10); //10 hosszan kiírva az eredmény "2147483647" delay(2000); double double_ertek_plusz=1739634352; //a double típus az ATMEGA vezérlőkön 4byte-os float érték, ami nem hosszabb, mint a normál float érték //így ez gyakorlatilag megegyezik a float-al, vagyis csak 1 egész és 7 tizedes érték és maximum 38 nulla //nagy számoknál az utolsó jegyeket már kerekíti és 00-val helyettesíti. Nem foglalkoztam vele, jó a float is lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Double érték:"); lcd.setCursor(0,1);lcd_uniprint((float) double_ertek_plusz,13,1); //a változó kijelzőre írása, utolsó kétjegyet felkerekíti a jobbról harmadik jegyre "1739634300.0" delay(2000); float float_ertek_plusz=23.7359; //létrehozunk egy float típusú változót, és feltöltjük pozitív összegű példával float float_ertek_minusz=-25.7359; //létrehozunk egy float változót és feltöltjük negatív összegű példával lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Float értek:"); lcd.setCursor(0,1);lcd_uniprint(float_ertek_plusz,0,3); //pozitív float érték 3 tizedesjegy hosszan, annyi helyet foglal amennyi kell lcd.setCursor(8,1);lcd_uniprint(float_ertek_minusz,8,4); //negatív float érték 4 tizedesjegy hosszan 8 hosszon kiírva delay(2000); time_24 ido24; //csinálunk egy time_24 típusú változót ido24.ora=5; //a time_24 típusú változónkban az óra értéke 5 óra (nullával kell kiegésszíteni) ido24.perc=4; // perc értéke 4 perc (nullával kell kiegészíteni) ido24.masodperc=3; // másodperc értéke 3 sec (nullával kell kiegészíteni) lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"24h mp nélkül:"); lcd.setCursor(0,1);lcd_uniprint(ido24,0); //24 órás kijelzés, és nincs másodperc a végén 05:04 delay(2000); lcd.clear();//LCD törlés lcd.setCursor(0,0);lcd_uniprint((String)"24h mp-el:"); lcd.setCursor(0,1);lcd_uniprint(ido24,1); //24 órás kijelzés, és van másodperc a végén 05:04:03 delay(2000); time_12 ido12; //csinálunk egy time_12 típusú változót ido12.ora=6; //a time_12 típusú változónkban az óra értéke 6 óra (nullával kell kiegészíteni) ido12.perc=2; // perc értéke 2 perc (nullával kell kiegészíteni) ido12.masodperc=1; // másodperc értéke 1 sec (nullával kell kiegészíteni) ido12.pm_am=HIGH; // délutáni időpont, így "pm" felirattal jelezzük, hogy délutáni időpont lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"12h pm mp-el:"); lcd.setCursor(0,1);lcd_uniprint(ido12,0); //12 órás kijelzés, délutáni időpont, és nincs másodperc a végén "06:02 pm" delay(2000); lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"12h pm mp-vel:"); lcd.setCursor(0,1);lcd_uniprint(ido12,1); //12 órás kijelzés, délutáni időpont, és van másodperc a végén "06:02:01 pm" delay(2000);//2 másodperc várakozás ido12.pm_am=LOW; // a változó délelőtti időpontot fog jelezni, "am" felirattal jelezzük, hogy délelőtti időpont lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"12h am mp-vel:"); lcd.setCursor(0,1);lcd_uniprint(ido12,0); //12 órás kijelzés, délelőtti időpont, és van másodperc a végén "06:02:01 am" delay(2000); datum ma;//csinálunk egy datum típusú változót ma.ev=2021; //a datum típusú változónkban az év értéke 2021 ma.ho=3; // ho értéke 3 perc (nullával kell kiegészíteni) ma.nap=15; // nap értéke 15 perc ma.hetnapja=4; // a hetnapja 4, azaz csütörtök lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Dátum évsz.-al:"); lcd.setCursor(0,1);lcd_uniprint(ma,0,1); //dátum évszázaddal, hét napja nélkül "2021.03.15" delay(2000); lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Dátum évsz.nélk:"); lcd.setCursor(0,1);lcd_uniprint(ma,0,0); //dátum évszázad nélkül, hét napja nélkül "21.03.15" delay(2000); lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"évsz.+hétnapja:"); lcd.setCursor(0,1);lcd_uniprint(ma,1,1); //dátum évszázaddal, hét napjával "2021.03.15 csütörtök" (a hét napja nem fér ki a 16 karakteres kijelzőn) delay(2000); lcd.clear(); lcd.setCursor(0,0);lcd_uniprint((String)"Dátum +hétnapja:"); lcd.setCursor(0,1);lcd_uniprint(ma,1,0); //dátum évszázad nélkül, hét napjával "21.03.15 csütörtök" (a hét napja nem fér ki a 16 karakteres kijelzőn) delay(2000); } void loop() { } void lcd_uniprint(long szam, byte min_fix_hossz) { /************************************************************************************************* Ez a függvény akkor hívódik meg, ha az első paraméter Long típusú és még egy Byte típusú * paraméter lett megadva. A megkapott Long típusú számot a Byte típusú változóval megadott * minimális hosszban megadott karakterszámon írja ki. Ha a második paraméter nulla, akkor a * számjegyek igényelt hosszának megfelelő helyet fog foglalni. Ha a számjegyek száma nagyobb, mint * a megadott minimum, akkor hosszabb helyet fog elfoglalni a kiíráskor a megadott szám. * **************************************************************************************************/ if (min_fix_hossz==0) {lcd_uniprint(String(szam));} //a megadott minimális hossz 0, annyi helyet foglal amennyi kell else { String str_tmp=String(szam); //betöltjük egy string típusú változóba byte hossz=str_tmp.length(); //megállapítjuk a hosszát if (min_fix_hossz>hossz) { //rövidebb mint a minimum for (byte i=0;i<(min_fix_hossz-hossz);i++) {str_tmp=" "+str_tmp;} //amennyivel rövidebb, annyi szóközt teszünk elé } lcd.print(str_tmp); //nincsenek ékezetek lehet használni az lcd.print()-et } } void lcd_uniprint(float szam,byte min_fix_hossz,byte tizedes) { /************************************************************************************************** Ez a függvény akkor hívódik meg, ha az első paraméter Float típusú és még két Byte típusú * paraméter lett megadva. A megkapott Float típusú számot az első paraméterben megadott * karakterszám hosszban írja ki, ha ez a paraméter nulla, akkor a számjegyek igényelt hosszának * megfelelő helyet fog foglalni. Ha a számjegyek száma nagyobb, mint a megadott minimum, akkor * hosszabb helyet fog elfoglalni a kiíráskor a megadott szám. A tizedes jegyek száma a harmadik * paraméterrel állítható be * ***************************************************************************************************/ if (min_fix_hossz==0) {lcd_uniprint(String(szam,tizedes));} //a megadott minimális hossz 0, annyi helyet foglal amennyi kell else { String str_tmp=String(szam,tizedes); //betöltjük egy string típusú változóba, megadjuk a String()-nek a tizedesjegyek számát byte hossz=str_tmp.length(); //megállapítjuk a hosszát if (min_fix_hossz>hossz) { //rövidebb mint a minimum for (byte i=0;i<(min_fix_hossz-hossz);i++) {str_tmp=" "+str_tmp;} //amennyivel rövidebb, annyi szóközt teszünk elé } lcd.print(str_tmp); //nincsenek ékezetek lehet használni az lcd.print()-et } } void lcd_uniprint(time_24 ido, bool kell_masodperc) { /************************************************************************************************** Ez a függvény megkap egy időpontot, amit 24 órás időpontnak feltételez. Az óra, perc és másodperc * értékét is megformázza oly módon, hogy mindig két karakter hosszú legyen, így az időpont kiírása * fix hosszúságú, pl.: „00:00:00”. Az óra, perc és másodperc értékeket ellenőrzi, és a kisebb és a * nagyobb értékeket minimumra (0-ra) illetve maximumra (23,59) helyettesíti. A time_24 típusú * változót várja első paraméterként, ennek változó tag nevei: * ora - a 24 órás időpont óra értéke * perc- a perc értéke * masodperc - a másodperc értéke * A második paraméter megszabja, hogy kérjük-e a másodperc kiírását. Ha értéke 0, akkor nem ír * másodpercet, csak az órát és perceket, ha értéke 1, akkor a teljes időpontot írja ki * „óra:perc:masodperc” formában! * ***************************************************************************************************/ //érték ellenőrzések és min max értékek beállítása, ha kell if (ido.ora<0) {ido.ora=0;} if (ido.ora>23) {ido.ora=23;} if (ido.perc<0) {ido.perc=0;} if (ido.perc>59) {ido.perc=59;} if (ido.masodperc<0) {ido.masodperc=0;} if (ido.masodperc>59) {ido.masodperc=59;} String str_tmp=""; //csinálunk egy üres stringet, ebbe fogjuk betölteni a formázott időpontot if (ido.ora==0) {str_tmp=str_tmp+"00";} //ha 0 az óra, akkor 00-át kell írni az óra helyére else { if (ido.ora<10) {str_tmp=str_tmp+"0"+String(ido.ora);} //ha kisebb mint 10, akkor elé kell írni egy 0-át else {str_tmp=String(ido.ora); } //ez egy kétjegyű óra időpont } str_tmp=str_tmp+":"; //most jönnek a percek if (ido.perc==0) {str_tmp=str_tmp+"00";} //ha a perc 0, akkor 00-át kell a percek helyére írni else { if (ido.perc<10) {str_tmp=str_tmp+"0"+String(ido.perc);} //ha a perc kisebb mint 10, akkor elé kell írni egy 0-át else {str_tmp=str_tmp+String(ido.perc);} //ez egy kétjegyű perc érték } if (kell_masodperc==1) { //csak ha kértük a másodperc kiírást, akkor folytatjuk, egyébként kész vagyunk str_tmp=str_tmp+":"; if (ido.masodperc==0) {str_tmp=str_tmp+"00";} //ha a másodperc 0, akkor 00-át kell a percek helyére írni else { if (ido.masodperc<10) {str_tmp=str_tmp+"0"+String(ido.masodperc);} //ha a másodperc kisebb mint 10, akkor elé kell írni egy 0-át else {str_tmp=str_tmp+String(ido.masodperc);} //ez egy kétjegyű másodperc érték } } lcd.print(String(str_tmp)); //nincsenek ékezetek lehet használni az lcd.print()-et } void lcd_uniprint(time_12 ido, bool kell_masodperc) { /******************************************************************************************************* Ez a függvény megkap egy időpontot, amit 12 órás időpontnak feltételez és „am” illetve „pm” jelzéssel * látja el a kiírt időt. Az óra, perc és másodperc értékét is megformázza oly módon, hogy mindig két * karakter hosszú legyen, így az időpont kiírása fix hosszúságú pl.: „am/pm 00:00:00” * Az óra, perc és másodperc értékeket ellenőrzi, és a kisebb és a nagyobb értékeket minimumra (0-ra) * illetve maximumra (12,59) helyettesíti. A time_12 típusú változót várja első paraméterként, ennek * változó nevei: * ora - a 12 órás időpont óra értéke * perc - a perc értéke * masodperc - a másodperc értéke * pm_am - ha értéke 0, akkor délelőtt, ha 1 akkor délután * A második paraméter megszabja, hogy kérjük-e a másodperc kiírását. Ha értéke 0, akkor nem ír * másodpercet, csak az órát és perceket, ha értéke 1, akkor a teljes időpontot írja ki * „óra:perc:masodperc” formában. * ********************************************************************************************************/ //érték ellenőrzések és min max értékek beállítása, ha kell if (ido.ora<0) {ido.ora=0;} if (ido.ora>12) {ido.ora=12;} if (ido.perc<0) {ido.perc=0;} if (ido.perc>59) {ido.perc=59;} if (ido.masodperc<0) {ido.masodperc=0;} if (ido.masodperc>59) {ido.masodperc=59;} String str_tmp; //csinálunk egy üres stringet, ebbe fogjuk betölteni a formázott időpontot if (ido.pm_am==0) {str_tmp="am ";} //ha pm_am=0, akkor ez délelőtt, és ekkor "am" et írunk az időpont elé else {str_tmp="pm ";} //ez délután, tehát "pm"-et írunk az időpont elé Serial.println(str_tmp); if (ido.ora==0) {str_tmp=str_tmp+"00";} //ha 0 az óra, akkor 00-át kell írni az óra helyére else { if (ido.ora<10) {str_tmp=str_tmp+"0"+String(ido.ora);} //ha kisebb mint 10, akkor elé kell írni egy 0-át else {str_tmp=str_tmp+String(ido.ora); } //ez egy kétjegyű óra időpont } str_tmp=str_tmp+":"; if (ido.perc==0) {str_tmp=str_tmp+"00";} //ha a perc 0, akkor 00-át kell a percek helyére írni else { if (ido.perc<10) {str_tmp=str_tmp+"0"+String(ido.perc);} //ha a perc kisebb mint 10, akkor elé kell írni egy 0-át else {str_tmp=str_tmp+String(ido.perc);} //ez egy kétjegyű perc érték } if (kell_masodperc==1) { //csak ha kértük a másodperc kiírást, akkor folytatjuk, egyébként kész vagyunk str_tmp=str_tmp+":"; if (ido.masodperc==0) {str_tmp=str_tmp+"00";} //ha a másodperc 0, akkor 00-át kell a percek helyére írni else { if (ido.masodperc<10) {str_tmp=str_tmp+"0"+String(ido.masodperc);} //ha a másodperc kisebb mint 10, akkor elé kell írni egy 0-át else {str_tmp=str_tmp+String(ido.masodperc);} //ez egy kétjegyű másodperc érték } } lcd.print(String(str_tmp)); //nincsenek ékezetek lehet használni az lcd.print()-et } void lcd_uniprint(datum dat, bool kell_hetnapja, bool kell_evszazad) { /********************************************************************************************************* Ez a függvény megkap egy dátumot, és formázottan kiírja az LCD kijelzőre. Beállítható, hogy az évszázadot* is kiírja, vagy csak az év utolsó két jegyét. Beállítható, hogy a hét napját szövegesen is kiírja a * dátum érték után. A dátum kiírása fix hosszúságú: pl.: „2021.10.01” vagy „21.10.01” Az év, hó és nap * értékeket ellenőrzi, és kisebb nagyobb értékeket minimumra (0-ra) illetve maximumra (12,31,9999) * helyettesíti. Nem ellenőrzi a dátum helyességét és a hét napjának egyezőségét, tehát elfogadja * februárt 31 naposnak, és nem szól, ha egy nap péntek, valójában dátum szerint szombat. A datum típusú * változót várja első paraméterként, ennek változó nevei: * ev - az evszam * ho - a hónap * nap - a nap * hetnapja - a hét napja, 1 hétfő....7 vasárnap * A második paraméter azt adja meg, hogy kell-e kiírni szövegesen a hét napját. Ha értéke 0, akkor nem * kell kiírni, ha értéke 1, akkor a dátum mögé kiírja szövegesen. A leghosszabb szöveges kiírás a * "csütörtök", ez összesen +10 karakter, 16 karakteres LCD-n már nem fér ki. A harmadik paraméter * megszabja, hogy kérjük-e az évszázad kiírását. Ha értéke 0, akkor nem ír évszázadot pl. „21.10.01” ha * értéke 1, akkor kiírja az évszázadot pl. „2021.10.01” * **********************************************************************************************************/ //érték ellenőrzések és min max értékek beállítása, ha kell if (dat.ev<0) {dat.ev=0;} if (dat.ev>9999) {dat.ev=9999;} if (dat.ho<1) {dat.ho=1;} if (dat.ho>12) {dat.ev=12;} if (dat.nap<1) {dat.nap=1;} if (dat.nap>31) {dat.nap=31;} if (dat.hetnapja<1) {dat.hetnapja=1;} if (dat.hetnapja>7) {dat.hetnapja=7;} String str_tmp; //csinálunk egy üres stringet, ebbe fogjuk betölteni a formázott dátumot if (kell_evszazad==1) { //kell évszázad, tehát az év 4 jegyű lesz if (dat.ev==0) {str_tmp=str_tmp+"0000";} //Jézus születését akarjuk kiírni else { if (dat.ev<10) {str_tmp=str_tmp+"000"+String(dat.ev);} //10 nél kisebb, de nem nulla az év else { if (dat.ev<100) {str_tmp=str_tmp+"00"+String(dat.ev);} //az év 10-nél nagyobb, 100-nál kisebb else { if (dat.ev<1000) {str_tmp=str_tmp+"0"+String(dat.ev);} //ez év 100-nál nagyobb, de ezernél kisebb else str_tmp=str_tmp+String(dat.ev); //1000-nél nagyobb az év } } } } else { byte dat_tmp=dat.ev/100; //osztjuk százzal, így megkapjuk a századok számát (egészre csonkítva) dat.ev=dat.ev-(dat_tmp*100); //kivonjuk az évből a századok számának 100-szorosát, az pont az év utolsó két jegye if (dat.ev==0) {str_tmp=str_tmp+"00";} //ha az utolsó két jegy 0, akkor "00" kell kiírni else { if (dat.ev<10) {str_tmp=str_tmp+"0"+String(dat.ev);} //ha kisebb mint 10, akkor kell elé egy 0 else str_tmp=str_tmp+String(dat.ev); //épp kétjegyű } } str_tmp=str_tmp+"."; //ez év és a hó közé pontot teszünk if (dat.ho<10) {str_tmp=str_tmp+"0"+String(dat.ho);} //a hónap egyjegyű, így kell elé egy 0 else {str_tmp=str_tmp+String(dat.ho);} //kétjegyű a hónap str_tmp=str_tmp+"."; //a hónap és a nap közé is kell pont if (dat.nap<10) {str_tmp=str_tmp+"0"+String(dat.nap);} //egyjegyű a nap, kell elé 0 else {str_tmp=str_tmp+String(dat.nap);} //kétjegyű a nap if (kell_hetnapja==1) { //ki kell írni a hét napját is str_tmp=str_tmp+" "; switch (dat.hetnapja) { case 1: str_tmp=str_tmp+"hétfő ";break; case 2: str_tmp=str_tmp+"kedd ";break; case 3: str_tmp=str_tmp+"szerda ";break; case 4: str_tmp=str_tmp+"csütörtök";break; case 5: str_tmp=str_tmp+"péntek ";break; case 6: str_tmp=str_tmp+"szombat ";break; case 7: str_tmp=str_tmp+"vasárnap ";break; } } lcd_uniprint(String(str_tmp)); //itt már lehet hét napja szövegesen ékezettel, ezért az lcd_uniprint() függvényt használom } void lcd_uniprint(String szoveg) { /******************************************************************************************* Ez a függvény képes feltölteni a magyar ékezetes betűk (csak kis betűk, mert többre nincs * memória hely) karakterképét az LCD kijelzőre, ha üres String paraméterrel hívjuk meg. Ha a * paraméter nem egy üres string, akkor megkeresi az ékezetes betűket (2 byte-on kerülnek a * stringbe), eltávolítja az egyik felesleges byte-ot, a másikat pedig arra a kódra cseréli, * amit a kijelzőnek kell küldeni az adott user karakter megjelenítéséhez (0-7 kódok). * ********************************************************************************************/ Serial.println("szoveg"); String kiir=""; byte karakter; byte j=0; byte hossz=szoveg.length(); //az átvett string hossza if (hossz==0) { //üres karakterrel hívtuk meg a függvényt, ez azt jelenti, hogy feltöltjük a kijelzőt a magyar kerekterek képével byte tt[8] = {B10,B100,B1110,B1,B1111,B10001,B1111}; //á betű karakterképe lcd.createChar(0,tt); tt[0]=B10;tt[1]=B100;tt[2]=B1110;tt[3]=B10001;tt[4]=B11111;tt[5]=B10000;tt[6]=B1110; //é betű karakterképe lcd.createChar(1,tt); tt[0]=B10;tt[1]=B100;tt[2]=B0;tt[3]=B1110;tt[4]=B100;tt[5]=B100;tt[6]=B1110; //í betű karakterképe lcd.createChar(2,tt); tt[0]=B10;tt[1]=B100;tt[2]=B0;tt[3]=B1110;tt[4]=B10001;tt[5]=B10001;tt[6]=B1110; //ó betű karakterképe lcd.createChar(3,tt); tt[0]=B00101;tt[1]=B01010;tt[2]=B0;tt[3]=B1110;tt[4]=B10001;tt[5]=B10001;tt[6]=B1110; //ő betű karakterképe lcd.createChar(4,tt); tt[0]=B10;tt[1]=B100;tt[2]=B10001;tt[3]=B10001;tt[4]=B10001;tt[5]=B10011;tt[6]=B1101; //ú betű karakterképe lcd.createChar(5,tt); tt[0]=B00101;tt[1]=B01010;tt[2]=B0;tt[3]=B10001;tt[4]=B10001;tt[5]=B10011;tt[6]=B1101; //ű betű karakterképe lcd.createChar(6,tt); return; } for (byte i=0;i<hossz;i++) { //minden karakteren sorban végig megyünk if ((byte) szoveg[i]==195 or (byte) szoveg[i]==197) //ha a kerekter 195 vagy 197, akkor azt kihagyjuk az eredmény stringből és vesszük a következő karaktert { i++; karakter=(byte) szoveg[i]; kiir.concat(" "); //ez a hiányos C++ tudásom miatt van, mivel nem tudtam hozzáfűzni a 0-7 ASCII kódot, ezért hozzáfüzük egy szóközt, //amit a switch-ben lecserélek a megfelelő feltöltött karakter kódjára, illetve a karakterkészletben meglévő //ö és ü betű kódjára switch (karakter) { case 129: kiir.setCharAt(j,0);break; //Á //a j. pozicióban (utolsó hozzáfűzött karaktert cserélem a feltöltött karakter kódjára case 161: kiir.setCharAt(j,0);break; //á case 137: kiir.setCharAt(j,1);break; //É case 169: kiir.setCharAt(j,1);break; //é case 141: kiir.setCharAt(j,2);break; //Í case 173: kiir.setCharAt(j,2);break; //í case 147: kiir.setCharAt(j,3);break; //Ó case 179: kiir.setCharAt(j,3);break; //ó case 150: kiir.setCharAt(j,239);break; //Ö case 182: kiir.setCharAt(j,239);break; //ö case 144: kiir.setCharAt(j,4);break; //Ő case 145: kiir.setCharAt(j,4);break; //ő case 154: kiir.setCharAt(j,5);break; //Ú case 186: kiir.setCharAt(j,5);break; //ú case 156: kiir.setCharAt(j,245);break; //Ü case 188: kiir.setCharAt(j,245);break; //ü case 176: kiir.setCharAt(j,6);break; //Ű case 177: kiir.setCharAt(j,6);break; //ű } } else {kiir.concat(szoveg[i]);} //ez egy kijelzőn is megtalálható karakter, simán csak másoljuk j++; //egy karakterrel több van a kijelzőre irandó stringben } //SimulIde áramkör szimulátorban csak karakterenként lehet kiírni, mert ott //az lcd.print() függvény valamilyen okból stringet nem képes kiírni csak az első //karakterét. Ezt a három sort csak akkor használom, ha SimulIde-ben akarom futtatni //for (byte i=0;i<j;i++) { // lcd.print(kiir[i]); //} lcd.print(kiir); //..és akkor kiírjuk a kijelzőre az ékezetes kódokra cserélt szöveget }