60 nap alatt Arduino #16 - LCD-ből óra

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
zoldfulurozi
Újonc
Újonc
Hozzászólások: 9
Csatlakozott: 2018. június 13. szerda, 11:44

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Köszönöm, akkor ha az if után nincs kapcsos zárójel , akkor úgy működik, hogy ha logikai vizsgálat igaznak bizonyúl akkor végrehajtja a parancsot, ha pedig nem igaz, akkor egyszerűen megy tovább???
atilla
Biztosítékgyilkos
Hozzászólások: 65
Csatlakozott: 2016. május 10. kedd, 18:35

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Idézet:
"Az If utasítás segítségével ellenőrizhetünk 1-1 feltételt, azaz hogy a feltétel teljesül-e;
például egy analóg bemenőjel értéke meghalad-e egy szintet. Ha a feltétel teljesül,
akkor a feltételt követő kapcsos-zárójelben levő utasítások végrehajtódnak; ha pedig
nem, akkor kihagyásra kerülnek."
zoldfulurozi
Újonc
Újonc
Hozzászólások: 9
Csatlakozott: 2018. június 13. szerda, 11:44

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Nagyon köszönöm a választ , el voltam tévedve, azt gondoltam addig vár, amíg nem teljesül a feltétel.
Nagyon köszönöm a segítséget, a fórum és a levelek is nagyon sokat segítenek.
Észre vettem egy számomra érdekes dolgot. A Time library letöltése után a példa progit futtatva siet a lapom. 1000 mili-ként 0,932 milit. ( A referencia telefonhoz képest, ami a mobil szolgáltatótól pontosit). Ugyanezt a programot egy Mblock ME Aurigán ( Arduino mega 2560 ) futtatva durván 11 óra alatt késik 7 másodpercet.… Azt gondoltam, hogy egy ennyire ismert , használt lib csak is jól, pontosan működhet. Úgy tűnik a másolat, clone –lapokon mégsem olyan pontos.
Elsőre azt gondoltam volna, hogy az UNO-n csak is késhet, ha még egy LCD-t is hozzá illesztek, de nem siet..
Próbálkozom , hátha sikerül a Time. cpp file-ban elcsalnom egy kis időt.
time_t now() {
// calculate number of seconds passed since last call to now()
while (millis() - prevMillis >= 1000) {
// millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference
sysTime++;
prevMillis += 1000;// itt próbálom állítani, hátha.
#ifdef TIME_DRIFT_INFO
sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift
#endif
atilla
Biztosítékgyilkos
Hozzászólások: 65
Csatlakozott: 2016. május 10. kedd, 18:35

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Millis használatával nem lesz pontos az órád. A 0-ás timer 64-es előosztón megy ilyenkor. Az 250000, ha jól jár a 16 MHz-es rezonátorod.
A 250000-et a timer 256-tal osztja. Ez 976,5625 Hz, és nem 1000. Tehát ennyi pontatlanság van benne. Ezt a blink villogónál nem veszed észre, de egy óránál igen.
Állítsad be a 16 bites timert 1 Hz-re, és azzal időzítsél.
zoldfulurozi
Újonc
Újonc
Hozzászólások: 9
Csatlakozott: 2018. június 13. szerda, 11:44

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Köszönöm a válaszod, arra rájöttem közben, hogy nem érdemes bele nyúlni a file-ba, mert különben folyton összeomlik.
Amit leírtál sajnos egyelőre nekem nagyon magas, de köszönöm. Azt hiszem ez olyan izgalmas téma, amire időről időre vissza fogok térni :-)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

if...else:
https://www.arduino.cc/reference/en/lan ... ucture/if/

Ha nem használsz kapcsos zárójeleket, akkor csak a következő 1 utasításra vonatkozik a feltételes végrehajtás.

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

Mind a 3 formátumnak egyforma az eredménye.
if (x > 120) digitalWrite(LEDpin, HIGH);

if (x > 120)
digitalWrite(LEDpin, HIGH);

if (x > 120){ digitalWrite(LEDpin, HIGH); }
Ha több utasítást alkalmazol a feltétel vizsgálatban?
Akko csoportba kel zárni őket:

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

if (x > 120){
  digitalWrite(LEDpin1, HIGH);
  digitalWrite(LEDpin2, HIGH);
}                                 // all are correct

Avatar
csegebiga
Chipgyilok
Hozzászólások: 288
Csatlakozott: 2015. március 27. péntek, 21:27

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Hülyeséget írtam nem tudom törölni.
zoldfulurozi
Újonc
Újonc
Hozzászólások: 9
Csatlakozott: 2018. június 13. szerda, 11:44

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Isteni , jó, hogy egy csomó dologra segítőkész válaszokat kaphatok. Köszönöm szépen.
sanca21
Újonc
Újonc
Hozzászólások: 3
Csatlakozott: 2019. január 6. vasárnap, 22:09

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Sziasztok!
Elkészült az LCD órám. Jól működik, de másra nem használható.

// LCD óra. HF-3


#include <EEPROM.h>
#include <LiquidCrystal.h>


byte masodperc = 0; // Másodperc tároló.
byte perc = 0; // Perc tároló.
byte ora = 12; // Óra tároló.
byte bekapcsolasH;
byte bekapcsolasL;
word bekapcsolas; // belső változók

LiquidCrystal lcd (2, 3, 4, 5, 6, 7); // (RS, E, D4, D5, D6, D7)

void setup() {
Serial.begin(9600); // soros port: 9600 bps
lcd.begin(16, 2);
pinMode(13, OUTPUT); // D13: LED
digitalWrite(13, LOW); // D13 kikapcsolva
bekapcsolasH = EEPROM.read(2); // magas helyiértek
bekapcsolasL = EEPROM.read(1); // alacsony helyiértek
if (bekapcsolasH == 0xFF && bekapcsolasL == 0xFF) {
bekapcsolasH = 0; // figyeljük, hogy az EEPROM üres?
bekapcsolasL = 0;
}
bekapcsolas = word(bekapcsolasH,bekapcsolasL); // worddé alakitás
bekapcsolas = bekapcsolas + 1; // a számlálás es visszaíras
Serial.print(bekapcsolas); // kiíras
Serial.println(". bekapcsolás");
bekapcsolasH = bekapcsolas/256;
bekapcsolasL = bekapcsolas % 256;
EEPROM.write (1, bekapcsolasL);
EEPROM.write (2, bekapcsolasH);

lcd.setCursor (3,0); // Kurzor a megfelelő helyre.
lcd.print("Pontos ido"); // "Pontos ido" nyomtatása az 1. sorba.
lcd.setCursor (4,1); // Kurzor a megfelelő helyre.
lcd.print("12:00:00"); // Az óra 12:00:00-ról indul.
}
void loop() {

for (masodperc = 0; masodperc<60; masodperc++) {
lcd.setCursor (10,1); // 60 másodperces for ciklus
if (masodperc<10) { // 60 másodperces for ciklus
lcd.print("0"); // 60 másodperces for ciklus
} // 60 másodperces for ciklus
lcd.print(masodperc, DEC); // másodperc nyomtatás.
// 60 másodperces for ciklus
delay(400); // Késleltetés
digitalWrite(13, HIGH); // D13 bekapcsolva
delay(300); // Késleltetés
digitalWrite(13, LOW); // D13 kikapcsolva
}

perc = perc + 1; // Perc növelés.
lcd.setCursor (7,1); // Kurzor a megfelelő helyre.
if (perc >= 60) { // Perc figyelés, ha elérte a
perc = 0; // 60-at, akkor nullázzuk, és
ora++; // növeljük az óra regisztert is.
}
if (perc<10) { // Tíznél kissebb számoknál 0-át
lcd.print("0"); // írunk a tizes helyértékre
}

lcd.print(perc, DEC); // Perc nyomtatás.

lcd.setCursor (4,1); // Óra regiszter figyelése
if (ora >= 24) { // Ha elérte a 24-et, nullázzuk
ora = 0;
}
if (ora<10) { // Tíznél kissebb számoknál térközt
lcd.print(" "); // írunk
}
lcd.print(ora, DEC); // Óra nyomtatása

}
_jani_
DrótVégénSzéndarab
Hozzászólások: 28
Csatlakozott: 2019. február 26. kedd, 16:17

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Sziasztok! Én is elkészültem a saját fejlesztésű szoftveres órámmal. Gondolkodtam rajta, hogy érdemes-e megosztanom mert kicsit terjedelmes lett az előttem megosztottakhoz képet. Biztos tartalmaz sok mellékhajtást. De egyenlőre nem bántom... Idővel majd lehet legallyazom...
A program:

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

/* (17.)
   
            17. LCD I. HF

    Üzemóra számláló és szoftveres óra 
    (12:00-ás kezdéssel) LCD-s megjelenítéssel
    60 nap alatt Arduinó tanfolyam
    (c) TavIR http://www.tavir.hu  

    Feladat:
    El kell készíteni a bekapcsolás számláló és
    a szoftver alapú óra programját.
    A program értékeit az LCD-n kell megjeleníteni.
*/

#include <Wire.h>
#include <EEPROM.h>
#include <jm_PCF8574.h>
#include <LiquidCrystal_I2C.h>

                                  // Az LCD configurálása:
LiquidCrystal_I2C lcd(0x3F,16,2); 

                                  // Belső változók, EEPROM:
byte bekapcsolasH;
byte bekapcsolasL;
word bekapcsolas;

// Másodperc:
byte masodpercx10 = 0, masodpercx1 = 0, masodperc = 1;
// Perc:
byte percx10 = 0, percx1 = 0, perc = 1, flag = 0;
// Óra:
byte orax10, orax1, ora = 23, flag1 = 0;
// Nap:
byte   napx10 = 3, napx1 = 1, nap = 31, flag2 = 0;
int ido;

void setup() {
  
  pinMode(13, OUTPUT);        // D13 beépített LED
  digitalWrite(13, HIGH);
  
   lcd.init();
   lcd.clear();
   lcd.backlight(); 
   lcd.setCursor(0,0);        // Ez majd változhat...
   lcd.print("Bekapcs:");

/* EEPROM.olvasás(honnan)    
   A honnan = 0-65535.  Az eredmény = 0-255. */
  bekapcsolasH = EEPROM.read(2); // Magas helyiérték
  bekapcsolasL = EEPROM.read(1); // Alacsony helyiérték
  
  bekapcsolas = word (bekapcsolasH,bekapcsolasL);

// A bekapcsolás változó kiírása az LCD-re
  lcd.setCursor(8,0);   // Ez majd változhat...
  lcd.print(bekapcsolas);
  lcd.print(".");
  
  bekapcsolas++; 				// bekapcsolas = bekapcsolas + 1
  bekapcsolasH = bekapcsolas / 256; 	// A H kiszámítása.
  bekapcsolasL = bekapcsolas % 256; 	// L kiszámítása modulo-val
 
  EEPROM.write (1, bekapcsolasL); 	// EEPROM.irás (hova.mit)
  EEPROM.write (2, bekapcsolasH); 	// A hova = 0-65535. (cím)
                                  		// A mit = 0-255.    (adat)

}

void loop() {
  ido = millis()/1000; // Bekapcs-óta..  /1000 ( Tesznél /60)

// másodperc
  masodperc = ido % 60;          // Másodper számítás Modulo-val
  masodpercx10 = masodperc / 10; // Másodperc * 10
  masodpercx1 = masodperc % 10;  // Másodperc *  1
  lcd.setCursor(13,1);
  lcd.print(":");
  lcd.setCursor(14,1);           // Kiírás helye másodperc *10
  lcd.print(masodpercx10);
  lcd.setCursor(15,1);           // Kiírás helye másodperc *1
  lcd.print(masodpercx1);

// perc
     if (masodperc == 0) {
         if (masodperc ==0 && flag == 0) {
            perc++;
            flag++;  
            if (perc == 60 ) {
               perc=0;
            }
         }
     } else { flag = 0;}
       
  percx10 = perc / 10;
  percx1 = perc % 10;
  lcd.setCursor(11,1);            // Kiírás helye perc *10
  lcd.print(percx10);
  lcd.setCursor(12,1);            // Kiírás helye perc *1
  lcd.print(percx1);
     
  lcd.setCursor(10,1);
  lcd.print(":");
          
// óra
     if (perc == 0) {
         if (perc == 0 && flag1 == 0) {
            ora++;
            flag1++; 
         }
       if (ora == 24 ) {
           ora = 0;
       }
     } else { flag1=0; } 
     
  orax10 = ora / 10; 
  orax1 = ora % 10;
  lcd.setCursor(8,1); // Kiírás helye ora*10. Ha 0 akkor szóköz!
    if (orax10 == 0 ) {
    lcd.print(" ");
    } else {lcd.print(orax10); }  
  lcd.setCursor(9,1); // Kiírás helye ora*1
  lcd.print(orax1);
     
// nap                        
     if (ora == 0 ) {
         if (ora == 0 && flag2 == 0) {
             nap++;
             flag2++; 
             if (nap == 32 ) {
                 nap = 1;
             }
       }
     } else { flag2 = 0; }

  napx10 = nap / 10; 
  napx1 = nap % 10;
  lcd.setCursor(0,1);
  lcd.print("nap:");
  lcd.setCursor(4,1); // Kiírás helye nap*10 Ha 0 akkor szóköz!
    if (napx10 == 0 ) {
    lcd.print(" ");
    } else {lcd.print(napx10); }
  lcd.setCursor(5,1); // Kiírás helye nap*1
  lcd.print(napx1);
  lcd.print(".");

// és menne tovább a matek ha kellene...
}
Igen. Sok IF feltételt használtam a fals beszámolások kiküszöbölésére. Ezért is került bele a flag (zászló) változó.
Sok lett a LCD pozicionáló utasítás is. Így karakterenként adhattam meg a pozíciót... ( Saját karakterkészletnél lesz jelentősége. )
Pár napja még azt sem tudtam, hogy fogom feléleszteni a kijelzőt I2C buszon. Így biztos elsiklottam pár dolog felett.
Az óra alapjelét a

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

 ido = millis()/1000; // Bekapcs-óta..  /1000 ( Tesznél /60)
utasítással képeztem le.
Szemmel jól működött ezért nem is gondolkodtam még más megoldáson. Nem mértem utána, hogy valóban 1S-et ad-e.
( Napok számlálása nem volt része a feladatnak, inkább csak próba volt. ( PL: napi - heti időzítés... )
A helyi értékek kiszámításához a

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

  orax10 = ora / 10; 
  orax1 = ora % 10;
(sima egész osztás és maradékképzést Modulo-t ) használtam.
Ha jó eredményt adnak minek kellene hosszan törpölni a feladattal.
Köszönöm, hogy ellenőrzitek a leckém! :wink:
by _jani_ :wink:
_jani_
DrótVégénSzéndarab
Hozzászólások: 28
Csatlakozott: 2019. február 26. kedd, 16:17

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

Sziasztok!
A FLAG változóról pár szó:

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

 // perc
     if (masodperc == 0) {
         if (masodperc ==0 && flag == 0) {
            perc++;
            flag++; 
            if (perc == 60 ) {
               perc=0;
            }
         }
     } else { flag = 0;}
     
A lényege az, hogy a perc értékhez csak egyszer legyen +1 hozzáadva, azalatt az idő alatt, amíg a " masodperc == 0 " feltétel igaz.
Így a főprogram bármennyiszer lefuthat 1Sec alatt, az értéket nem módosítja. ( DEALY-val kipróbáltam. :wink: )
Az óra és nap feltételeinél, lehet nem kellenek, de biztosra mentem... :roll:
( Az óra ideiglenes lefagyását /DELAY>1000/ nem kezeltem le. De nem is volt feladat... )
by _jani_ :wink:
_jani_
DrótVégénSzéndarab
Hozzászólások: 28
Csatlakozott: 2019. február 26. kedd, 16:17

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

S látom már, hogy hol lehet egyszerűsíteni! Ki is próbálom...
by _jani_ :wink:
_jani_
DrótVégénSzéndarab
Hozzászólások: 28
Csatlakozott: 2019. február 26. kedd, 16:17

Re: 60 nap alatt Arduino #16 - LCD-ből óra

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

A program ( Csak amin változtattam. ) :

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


// Elég egy "flag" változó. A többi nem kell...
byte flag = 0;

...
// Másodperc kiírása - programrész...


// perc
     if (masodperc == 0  && flag == 0) {
            perc++;
            flag++;  
            if (perc == 60 ) {
               perc=0;
            }
     } else { flag = 0;}
// Perc kiírása - programrész...

// óra
     if (perc == 0 && flag == 1) {
            ora++;
            flag++; 
       if (ora == 24 ) {
           ora = 0;
       }
     } else { flag1=0; } 
// Óra kiírása - programrész...

// nap                        
     if (ora == 0 && flag == 2) {
             nap++;
             flag++; 
             if (nap == 32 ) {
                 nap = 1;
             }
     } else { flag2 = 0; }
// Nap kiírása - programrész...

Vagyis a PERC feltétele masodperc == 0 && flag == 0 IGAZ? Akkor a FLAG változót is növelem eggyel. Eredmény: FALG=1.
Második: ÓRA feltétele perc == 0 && flag == 1 IGAZ? Akkor a FLAG változóhoz hozzáadok még egyet. Eredmény: FLAG=2.
Harmadik: NAP feltétele óra == 0 && flag == 2 IGAZ? Akkor a FLAG változóhoz hozzáadok még egyet. Eredmény: FALG=3.
Ha a feltételsor lefutott, az új ciklus vagy a hamis ágak törlik a FALG változót. Eredmény: FALG=0.
Amíg a FALG = 0, addig a hamis ágakon fog lefutni a feltételvizsgálat... ( Hamis ágak vizsgálata helyett mással is foglalkozhatna a uC. )

De emlékeztet ez az egyik eljárásfüggvényre...
A switch/case-ra.
A HAMIS (FALSE) ág lefutása után valóban nincs értelme a további feltételvizsgálatnak.
Mert minek is kellene megvizsgálni azt amiről biztosan tudjuk ( feltételezzük ), hogy az a kívánt eredményt tartalmazza.

Ha az eredmény kiírásánál is csak azokra koncentrálnék amik megváltoztak, lehet, hogy meg lehetne spórolni egy kis processzor időt is ! ?
by _jani_ :wink:
Válasz küldése