LCD ébresztőóra

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
scalesman
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2010. augusztus 31. kedd, 6:00

LCD ébresztőóra

Hozzászólás Szerző: scalesman »

A 32# leckében kapott mintaprogrammal vannak gondjaim , már lefordítani sem tudom , mivel hibát talál benne a fordító.

Kód: Egész kijelölése

/*  LiquidCrystal + óra
 LCD fuggvenykonyvtar
 A 2x16 karakteres LCD mintaprogram
 EXT1 aramkorre hangolva
Például ez a sor pontosan mit akarna jelenteni, merthogy formai hibás lásd lentebb:

Kód: Egész kijelölése

 void loop() {
  //Thhmmss ; Ahhmmxx (opc: Dyymmdd)
  if (Serial.available() > 0) {
    // var adat feldolgozasra?
    inByte = Serial.read();
    // 1 byte beolvasasa
    if ((inByte == 'T') ||
       (inByte == 'A') ||
       (inByte == 'D') ||
       ((inByte >= '0') && (inByte 1000) /EZ ITT FORMAI HIBAS
  {
    mp++;
    kiiras();
    start_time+=1000;
  }
}
} 
Talán esetleg így nézne ki?:

Kód: Egész kijelölése

void loop() {
  //Thhmmss ; Ahhmmxx (opc: Dyymmdd)
  if (Serial.available() > 0) {
    // var adat feldolgozasra?
    inByte = Serial.read();
    // 1 byte beolvasasa
    if ((inByte == 'T') ||
      (inByte == 'A') ||
      (inByte == 'D') ||
      ((inByte >= '0') && (inByte =1000)))
    {
      mp++;
      kiiras();
      start_time+=1000;
    }
  }
}
A kiiras() függvény nincs definiálva a programban, mit kellene neki kiirnia?
Bocsánat , de jobbára csak kipróbálva próbálom megérteni a programok működését, kicsit lemaradtam .
Van egy nyomógomb a D3-on a GND felé. Hogyan is kellene pontosan működnie az áramkörnek? Ha jól értem , akkor soros monitor programban tudnám beállitani az órát, az ébresztés idejét és a dátumot? Mi funkciója van a nyomógombnak. Nekem egyenlőre nem jelenik meg semmi a kijelzőn.

Kód: Egész kijelölése

void setup() {
  //ebresztes();
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  //hatter bekapcsol EXT1 eseten 

  //D3 GND fele nyomogomb, felhuzo
  pinMode(3,INPUT);
  digitalWrite(3, HIGH);

  Serial.begin(9600);
  //Sorosport 9600 bps nyitasa

  lcd.createChar(1, orakep);
  lcd.createChar(2, ebreszt);
  lcd.begin(16, 2);
  //2x16-os LCD van
  start_time = millis();
  Serial.println("Start Clock...");  
}
Ha az ebresztes() függvényt nem kommentelem ki , akkor egy pillanatra felvillan a kijelzőn a 12:15:56 időpont, de utána semmi nem látszik a kijelzőn. A soros monitorban a "Start Clock " felirat jelenik meg.
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Re: LCD ébresztőóra

Hozzászólás Szerző: SzLacus »

Nem elmerülve a problémában, a következőt tudom hozzáfűzni.
Az lcd-re, az installálása után hasonló módon tudsz kiírni mint a soros portra. Vagyis ahogy van Serial.print(), ugyanúgy van lcd.print(). A kiiras() függvényben valami lcd.print() dolognak kell lennie. Mivel egyedi karaktereket definiáltál (óra, ébresztés) azokat lcd.write() függvénnyel tudod megjeleníteni. Az lcd-re írás annyiban különbözik a sorosportra írástól, hogy míg a képernyődön bármilyen hosszú szöveget meg tudsz jeleníteni, és látni fogod kélsőbb is, addig az lcd-n 2 sorod és 16 karaktered van. Ami ezen kívülre esik, az is kimegy az lcd-nek, csak nem fogod látni. Pontosabban, ha elég hosszú, akkor előbb utóbb megint bekúszik a kijelzőre.
Vagyis ha új szöveget akarsz kiírni, akkor a kurzort a szöveg kezdetének helyére kell állítanod, csak utána mehet a print paracs. Nézd meg az lcd memória kiosztását, és az lcd könyvtár függvényeit.
Még egy apróság. Jól megtaláltad, hogy az inByte és az 1000 között nem volt reláció. De amit te odaírtál az nem úgy fog működni ahogy várod tőle. Azért nem mert az ott egy érték adás, nem pedig egyenlőség vizsgálat. Amit írtál az mindíg igaz lenne, ha az és feltétel első fele teljesül. Azért, mert az inByte =1000 az önmagában már igaz. De sokkal valószínűbbnek tartom, hogy abban a feltételben nulla és ezer közti számot várunk.
Bazs87
Biztosítékgyilkos
Hozzászólások: 62
Csatlakozott: 2014. július 20. vasárnap, 20:27

Re: LCD ébresztőóra

Hozzászólás Szerző: Bazs87 »

Sziasztok!

Elnézést, hogy ide ömlesztem a problémát, de a barátom, gugli sem tudott segiteni:)

A következő a problémám: van egy void alprogramom(time_change), amiben 2 konstans értéket szeretnék változtatni. Az alprogramot gyönyörűen meghívja, de a konstans marad a régiben, hiába szeretném írni. Nincs valami tippetek mit kell módosítanom, hogy az én elgondolásom szerint fusson mindez? Az int meg a result-os megoldás elvileg felejtős, mert az elvileg csak egy értéket ad vissza.

a kód:

Kód: Egész kijelölése

#include <DHT.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity

#define DHTPIN 2  
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

//ora
byte mp, perc, ora, nap, oldsec, oldmin, oldhour;
unsigned long starttime, endtime;

byte tempC;
byte oldtemp;
byte hum;
byte oldhum;

void setup() {
  lcd.backlight();
  lcd.begin(16,2);

  ora=23;
  perc=59;
  mp=56;

  oldsec=0;
  oldmin=0;
  oldhour=0;
  oldtemp=0; 
  oldhum=0;

lcd.setCursor(2,0); 
lcd.write(":");  
lcd.setCursor(5,0); 
lcd.write(":"); 
lcd.setCursor(15,0); 
lcd.write("C"); 
lcd.setCursor(15,1); 
lcd.write("%"); 
}

void loop() {
  starttime=millis();
  
  mp++;
  
  timecount(mp,perc,60);
  timecount(perc,ora,60);
  timecount(ora,nap,24);
 
  tempcheck();
  humcheck();

  lcd_write(ora,oldhour,0,0);
  lcd_write(perc,oldmin,3,0);
  lcd_write(mp,oldsec,6,0);

  lcd_write(tempC,oldtemp,12,0);
  lcd_write(hum,oldhum,12,1);

  endtime=millis();  
  delay(1000-endtime+starttime);
}


void tempcheck(){
    // Read temperature as Celsius
  float t = dht.readTemperature();
  tempC=round(t);  
}

void humcheck(){
    // Reading humidity as %
    float h = dht.readHumidity();
    hum=round(h);
}

int timecount(byte b_mp, byte b_min, byte b_step){ 
  if (b_mp == b_step) {
    b_mp=0;
    b_min++; 
  }
}

void lcd_write(byte b_write, byte b_chk, byte b_nkar, byte b_oszl) {
  if (b_chk != b_write) {
    lcd.setCursor(b_nkar,b_oszl);
    if (b_write<10) {lcd.write("0");  }  
    lcd.print(b_write,DEC); 
    b_chk=b_write; 
  }
}

sajnos a #29. leckéig bezárólag nem találtam erre megoldást

Köszönöm előre is!
Az esetleges rövidítési, optimalizálási tanácsokat is szívesen venném.

Üdv!
Bazs87
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: LCD ébresztőóra

Hozzászólás Szerző: Robert »

A programodban nincs ilyen függvény.
A konstans jelentése: fix érték. Nem változtatható. Az a változó, ami neked kell. Definiáld konstans helyett word, long vagy a változónak megfelelő típusúként.
Bazs87
Biztosítékgyilkos
Hozzászólások: 62
Csatlakozott: 2014. július 20. vasárnap, 20:27

Re: LCD ébresztőóra

Hozzászólás Szerző: Bazs87 »

sajnos a szóhasználat nem volt megfelelő, globál deklarált mp, perc és óra amihez a kérdésem volt, azok viszont byte-ként deklarálva vannak.
Bazs87
Biztosítékgyilkos
Hozzászólások: 62
Csatlakozott: 2014. július 20. vasárnap, 20:27

Re: LCD ébresztőóra

Hozzászólás Szerző: Bazs87 »

a problémás függvény helyes neve pedig timecount, nem timechange, ami szinten deklarálva van
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: LCD ébresztőóra

Hozzászólás Szerző: Robert »

A függvényben hazsnált belső változód (b_min) növelődik eggyel. nem pedig a globális min nevű. A belső változó a függvényből kilépéskor megszűnik létezni.
Bazs87
Biztosítékgyilkos
Hozzászólások: 62
Csatlakozott: 2014. július 20. vasárnap, 20:27

Re: LCD ébresztőóra

Hozzászólás Szerző: Bazs87 »

és hogyan tudok úgy dinamikusan meghívni egy változót, hogy a függvényből való kilépéskor írni is tudjam? van erre mód? Köszönöm válaszod!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: LCD ébresztőóra

Hozzászólás Szerző: Robert »

??
Egy példát tudnál írni?
Szóban. Mikor mi történik. A kérdést nem értem.

Illetve lehet:

A függvényed rendelkezik ún visszatérési értékkel. Azaz nem void valami(), hanem int valami().
Ekkor mint egy függvényt használod:
fovaltozo=valami();
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Re: LCD ébresztőóra

Hozzászólás Szerző: SzLacus »

Globálisnak definiáltad, vagyis bárhonnan eléred. Nem számít, hogy a setupban vagy a loopban macerálod, és az sem hogy saját függvényben akarod változtatni.
Növelgesd azt egyből és felejtsd el a függvényben létrehozott helyi változót. Vagy meghagyhatod, és a növelés után egyelővé teszed a globálist a helyivel, aztán veszhet a lokális váltzód, nem hiányzik senkinek.
Bazs87
Biztosítékgyilkos
Hozzászólások: 62
Csatlakozott: 2014. július 20. vasárnap, 20:27

Re: LCD ébresztőóra

Hozzászólás Szerző: Bazs87 »

a kód még mindig a "régi":

void timecount(byte b_mp, byte b_min, byte b_step){
if (b_mp == b_step) {
b_mp=0;
b_min++;
}
}

használata:
timecount(mp,perc,60);

ebbe írogatom bele a másodperc, perc, óra byte-okat. Viszont az int-es megoldás nem passzol, mert én két dinamikus változót szeretnék írni, a resultsnak meg csak egy értéke van. (szeretném a mp-et és a percet is írni, viszont nem tudom hogyan tudnám a függvény végén a változót dinamikusan meghívni, )vagyiis b_min=perc ....de a perc értéke épp a b_min változóban pihen, ami viszont a függvény végeztével nem olvasódik vissza a perc változóba

Az órához van megoldásom, csak a dallamos leckében volt szó arról, h ne másolgassuk a sorokat, mert így takarékosabb. Mivel épp a függvényeknél tartok így most mindent egyszerűsíteni szeretnék. Sajnos ebbe picit beletört a bicskám.

ha azt mondjátok hülyeség és nem kéne ilyenen pörögni maradok a kitaposott úton, de szeretem kicsit hajlítgatni a dolgot, mert így értem meg ténylegesen. Ha most ebbe nem barbárkodom bele ezeket az infókat meg se kapom:)
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Re: LCD ébresztőóra

Hozzászólás Szerző: SzLacus »

Ki kell próbálni mindent, ami eszedbe jut, a tapasztalás a legjobb tanulás. Néha drága, de jól rögzül. :)
De a felvetésre visszatérve, hiányzik a rutin végéről, az a sor, amiben a rutin lokális változóján elvégzett művelet eredményét a mp változódba viszed. és persze ugyan ezt kell tenned a perccel is, mert ugye két dolog is változik egyeszerre.
Ha egy függvény hívásban a függvényednek átadod a szükséges paramétert, akkor a függvény egy másolatot kap a változódról, amivel dolgozni fog. Elvégzi rajta amit kell, és a másolattal kell valamit kezdened a végén. Például valamelyik (mp) globális változódnak az értékét egyenlővé teszed vele.
Ha viszont a függvényedet úgy írod meg, hogy benne közvetlenül a globális változóval végzed a műveletet, akkor direktben kapod az eredményt. És még az is lehet, hogy a függvényed nem void, hanem mondjuk byte, és akkor a végén egy return-al adod vissza a byte méretű lokális változódat. Ekkor a hívás helyén "változó = függvény" formát fogsz használni.
Vannak még további játszóterek, pl cím alapú paraméter átadás, de ezekbe most ne bonyolódjunk bele.

Még egy apróság, de ez egyéni ízlés dolga. Nekem tetszik, hogy ugyan azt a függvényt hívod az idő elemek túcsordulásának kezelésére. A függvényben a változókat én nem b_mp és b_perc elnevezéssel illetném, mert perc óra, és óra nap értékekkel is használódik. Hanem valami ráutalóbbat találnék ki neki, amiből látom utólag is kapásból, hogy a vizsgált érték, hova csordul át, és váltó határ az amivel dolgozni fog az eljárás. Ez csak az utólagos megértést segítheti és valószínűleg csak nekem, de ha más is olvassa a kódomat akkor talán hamarab megérti mit szerettem volna leírni. Az ide vonatkozó mondás szerint a zseni a káoszban is megtalálja, csak a hülyéknek van szüksége a rendre. Én nem tartozom a zsenik közé. :)

Még egy dolog, amit érdemes figyelned, hogy miként változik a programod mérete, ha leírod kétszer, vagy akár háromszor azt a pár sort más-más értékekkel, vagy kipakolod függvénybe, és paraméterekkel hívod. Nem mindíg egyértelmű a nyereség. Van az a méret, amit még nem érdemes függvénybe rakni, ha spórolni kell a hellyel, annak ellenére, hogy a kód jobban néz ki, és sokkal kezelhetőbb.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: LCD ébresztőóra

Hozzászólás Szerző: Robert »

Ami kérdés: ha két változó kell hogy változzon, akkor azt tedd a függvényben.
A függvényed ha rendelkezik visszatérési értékkel, az egy lehet.

Ha nagyon el akarod bonyolítani, akkor lehet egy kételemű tömb is...

Válaszd azt az utat, ami működik. Vagy ami kényelmes.
A kódméret viszont jó tanulság....:)
Bazs87
Biztosítékgyilkos
Hozzászólások: 62
Csatlakozott: 2014. július 20. vasárnap, 20:27

Re: LCD ébresztőóra

Hozzászólás Szerző: Bazs87 »

a 2 elemű tömb módosítása érdekelne, még ha elég perverz is. Tudnál mutatni egy példát? Köszönöm válaszod!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: LCD ébresztőóra

Hozzászólás Szerző: Robert »

A függvényt definiálod:

Kód: Egész kijelölése

void loop()
{
 byte data[2];
 getdat(data);
}

void getdat(byte pdata[])
{
 pdata[0] = 'a';
 pdata[1] = 'b';
}

Illetve globális elven

Kód: Egész kijelölése

void getdat(byte &one, byte &two)
{
    one = 1;
    two = 2;
}

byte a=13, b=26;
getdat(a, b);

Válasz küldése