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

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
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 »

Erre csak annyit felelhetek, hogy ami nincsen azt meg kel írni!
Elvégre programozást tanulsz!

Pl.: a Te kérdésedre:

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

#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7, 8 );

int bekapcsolas = 1;

//  változóra
void mylcdprint(char *theText, int num){
  lcd.print(theText);
  lcd.print(num);
}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  
  myprint("Bekapcsolas: ", bekapcsolas);
  
}
Jazzkedvelo
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2014. december 8. hétfő, 20:03

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

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

Ok, de itt még ilyeneket nem vettünk. Objektumorientáltság, mutatók, stb.

Szóval ez itt nem ér :-)

(egyébként egy pici hiba van a sorokban)
Jazzkedvelo
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2014. december 8. hétfő, 20:03

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

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

Kicsit játszottam a karakterkészlettel meg a beépített karakterkódokkal. Íme egy nagyon egyszerű program, ami fellapozza nekünk a kijelzőn a különböző címeken található karaktereket:

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

#include "LiquidCrystal.h"

LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

int n;
   
void setup() {
   pinMode(13, OUTPUT);
   digitalWrite(13, HIGH);
   lcd.begin(16, 2);
}
 
void loop()
{
  for (n=0; n<=255; n++)
    {
    lcd.clear(); 
    lcd.print(n);
    lcd.print("  ");
    lcd.write(n);
   
    delay(500);
    }
}
Az érdekesség ott jött elő, hogy van 3 féle 16x2-es kijelzőm is, mindegyik elvileg 1602a kompatibilis cucc. Aztán amikor végiglapoztam a karaktereket, jött a meglepi - bizony jelentősen eltérnek a karakterek egymástól. Az alsó 128 címen a latin betűk stimmelnek, de sok egyéb karakter nem, a "második" 128 címen pedig ég és föld. Ráadásul volt vagy 10 20 hely üres is, ahol semmi nem jelent meg, azaz értelmezni nem sikerült.

Ettől függetlenül megtaláltam mindegyikben az ékezetes karaktereket, így nem kellett definiálni feltétlenül (persze tök jó hogy "tanfolyamfelelős" megtanítja nekünk hogy kell, mert lehet minden egyedit is csinálni vele).

Az egyik kijelzőre íme egy progi, ami definiálás nélkül jól használja ezeket, de nem garantált hogy más gyártónál ugyanez van beégetve a karakterkészletbe.

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

#include "LiquidCrystal.h"

LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
 
byte b, s=0, o=0;
 
void setup() {
   pinMode(13, OUTPUT);
   digitalWrite(13, HIGH);

  lcd.begin(16, 2);
  Serial.begin(9600);   
}
 
void loop()
{
  if (Serial.available()) 
  {
    b = Serial.read();
    Serial.print(b);
    Serial.print(":");
     
    if (b == 246) { b = 148;} //ö
    if (b == 237) { b = 161;} //í
    if (b == 225) { b = 160;} //á
    if (b == 233) { b = 130;} //é
    if (b == 243) { b = 162;} //ó
    if (b == 245) { b = 173;} //ő
    if (b == 250) { b = 163;} //ú
    if (b == 251) { b = 150;} //ű
    if (b == 252) { b = 129;} //ü
    
    Serial.println(b,DEC);
    lcd.write(b);
    o++;
    if (o==16) {o=0; s++; lcd.setCursor(o,s);}
    if (s==2) {lcd.clear(); o=0; s=0;lcd.setCursor(o,s);}
   }
}
Mondjuk a hosszú ű és ő nem tökéletes, de "belefér a kompromisszumokba", legalábbis nálam.
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 »

Ilyen jellegű feladat esetén az if-ek helyet használd inkább a switch / case –t!

Kisebb és gyorsabb kódot kapsz, és pont erre találták ki.
http://arduino.cc/en/Reference/SwitchCase
Jazzkedvelo
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2014. december 8. hétfő, 20:03

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

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

Igaz amit írsz, de itt csak játszottam vele.

A gyorsasága meg itt nem volt szempont, ez csak egy "segédprogram". Persze a switch már csak azért is gyorsabb, mert nem vizsgálja végig az összes feltételt, hanem ha az egyik igaznak bizonyult, utána kiugorhatunk belőle, és nem kell vizsgálni a többit.

És akkor még tovább "optimalizálható" a betűsorrenddel is, biztos van valami statisztika, mely ékezetes betük milyen arányban fordulnak elő a szavakban, és ennek megfelelően sorrendbe lehet állítani őket.
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 »

Elnézést!

Én csak biztatni akartalak, hogy (Nem vagy egyedül!) játsszál tovább!
:lol:
Jazzkedvelo
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2014. december 8. hétfő, 20:03

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

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

Értem én, és köszönök minden segítséget :-).
Jazzkedvelo
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2014. december 8. hétfő, 20:03

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

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

Meglett a nagyjából kész ébresztőóra, a milis() használatával méri az időt. Így amennyire ez téved, annyira pontos. A (közel)teljes kód már 7 kbyte, azaz nem kevés.

Ide be is másolom, de nem rövid.

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

#include <pitches.h>
#include "LiquidCrystal.h"

LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

byte ora, perc, mp; //aktuális ido
byte EORA=22, EPERC=30, EMP=00; //ébresztési idő megadása
unsigned long ORA=22, PERC=30, MP=25; //pontos idő megadása

unsigned long ido; //milisec alapu idő a bekapcsolas óta

int melody[] = {
  NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
 
int noteDurations[] = {
  4, 8, 8, 4,4,4,4,4 };
  
void alapkepernyo()
    {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Ido:      :  :");
    lcd.setCursor(0, 1);
    lcd.print("Vekker:");
    lcd.setCursor(8, 1);
      if (EORA<10)
        {
         lcd.print("0");
         lcd.print(EORA);
         }
         else
         {
          lcd.print(EORA);
         }
    lcd.print(":");
    if (EPERC<10)
        {
         lcd.print("0");
         lcd.print(EPERC);
        }
        else
        {
        lcd.print(EPERC);
        } 
    lcd.print(":");
    
      if (EMP<10)
        {
         lcd.print("0");
         lcd.print(EMP);
        }
        else
        {
        lcd.print(EMP);
        } 
    }
    
void idomeghatarozas()
    {
    ido = millis();
    //alapértékek kiszamolasa a millis() ertekebol
    mp= ((ido+1000*MP) % 60000)/1000;
    perc=((ido+mp+1000*MP+60000*PERC) % (60*60000))/60000;
    ora= ((ido+mp+perc+1000*MP+60000*PERC+(60000*60*ORA)) % (24*60*60000))/(60000*60); 
    }
    
void ebresztes()
    {
        lcd.setCursor(0, 1);
        lcd.print("    Ebreszto!    ");
        
        // zenelejatszas
        for (int thisNote = 0; thisNote < 9; thisNote++) 
                {
                int noteDuration = 1000/noteDurations[thisNote];
                tone(10, melody[thisNote],noteDuration);
                int pauseBetweenNotes = noteDuration * 1.30;
                delay(pauseBetweenNotes);
                if (thisNote==8) {delay (1000); thisNote=-1;}
                if (digitalRead(3)==0) 
                    {
                      noTone(10); 
                      lcd.setCursor(0, 1);
                      lcd.print("    Epp ideje!");
                      delay(2000); 
                      thisNote=9;  
                      alapkepernyo();
                    }
                }
     }
    
void idokiiras()
    {
    lcd.setCursor(14, 0);
    if (mp<10)
        {
         lcd.print("0");
         lcd.print(mp);
         }
         else
         {
         lcd.print(mp);           
         }
                      
    lcd.setCursor(11, 0);
      if (perc<10)
        {
         lcd.print("0");
         lcd.print(perc);
         }
         else
         {
         lcd.print(perc);           
         }
   
    lcd.setCursor(8, 0);
      if (ora<10)
        {
         lcd.print("0");
         lcd.print(ora);
         }
         else
         {
         lcd.print(ora);           
         }
    }
    
void beallitas() // ebreszto és óra beallitasa
    {
    byte sora, sperc, smp; //idoallitas segéd
    
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Ebreszto allitas");
    lcd.setCursor(0, 1);
    lcd.print("Ora:");
    delay (2000);
    while(digitalRead(50)==1) //Ébresztő óra állítás
        {
          lcd.setCursor(10, 1);
            if (EORA<10)
            {
             lcd.print("0");
             lcd.print(EORA);
             }
             else
             {
             lcd.print(EORA);           
             }
          if (digitalRead(51)==0) 
              {
                EORA++;
                delay (500);
                if (EORA==24)
                  {
                  EORA=0;
                  }
               }
            
          }
      delay (500);
      
      lcd.setCursor(0, 1);
      lcd.print("Perc:");    
    
      while(digitalRead(50)==1) //Ébresztő perc állítás
        {
          lcd.setCursor(10, 1);
            if (EPERC<10)
            {
             lcd.print("0");
             lcd.print(EPERC);
             }
             else
             {
             lcd.print(EPERC);           
             }
          if (digitalRead(51)==0) 
              {
                EPERC++;
                delay (500);
                if (EPERC==60)
                  {
                  EPERC=0;
                  }
               }
            
        }
    delay (500);
     
    sperc=perc;   // Idő beállítása
    sora=ora; sperc=perc;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Ido beallitas");
    lcd.setCursor(0, 1);
    lcd.print("Ora:");
    delay (2000);
    while(digitalRead(50)==1) //Óra állítás
        {
          lcd.setCursor(10, 1);
            if (sora<10)
            {
             lcd.print("0");
             lcd.print(sora);
             }
             else
             {
             lcd.print(sora);           
             }
          if (digitalRead(51)==0) 
              {
                sora++;
                delay (500);
                if (sora==24)
                  {
                  sora=0;
                  }
               }
          }
          
      if (sora>=ora)  //ORA meghatározása a beírt beállításból
          {ORA=ORA+(sora-ora);}
        else
          {ORA=ORA+(24-(ora-sora));}      
      
      delay (500);
      
      lcd.setCursor(0, 1);
      lcd.print("Perc:");    
    
      while(digitalRead(50)==1) //Perc állítás
        {
          lcd.setCursor(10, 1);
            if (sperc<10)
            {
             lcd.print("0");
             lcd.print(sperc);
             }
             else
             {
             lcd.print(sperc);           
             }
          if (digitalRead(51)==0) 
              {
                sperc++;
                delay (500);
                if (sperc==60)
                  {
                  sperc=0;
                  }
               }
        }
        
        if (sperc>=perc)  //PERC meghatározása a beírt beállításból
          {PERC=PERC+(sperc-perc);}
        else
          {PERC=PERC+(60-(perc-sperc));ORA=ORA-1;}

    delay(2000);
    alapkepernyo();
    }
    
void setup() {
    pinMode(3, INPUT); //ebreszto leallitas gomb
    pinMode(50, INPUT); //beallitas gomb
    pinMode(51, INPUT); //ertekadas gomb
    
    pinMode(30, OUTPUT); //+ tap
      digitalWrite(30, HIGH);
    pinMode(31, OUTPUT); //GND
      digitalWrite(31, LOW);
    
    pinMode(13, OUTPUT); //háttérvilágítás
        digitalWrite(13, HIGH);
    lcd.begin(16,2);
    alapkepernyo();  
}
 
void loop() 
{
  
    idomeghatarozas();
    idokiiras();
    if (digitalRead(50)==0)//beállítás
      {
      delay (500);
      beallitas();
      }
    
    if (EORA==ora && EPERC==perc && EMP==mp) //ébresztő és óra egyezik
       {
       ebresztes();   
       }  
}
Van azért pár hozzáfűznivaló is:
1. Két definiált nyomógombbal állítható mind az ébresztő, mind az óra. Az egyik gomb a kiválasztás, mit akarunk állítani, a másik gombbal pedig léptetjük az értéket.
2. A nyomógombok hirtelen ötlettől vezérelve - még ha nem is jó megoldás - a 30-31 pin-ről kapják a tápot, földet, amit a mikrovezérlő kapcsol, természetesen külső ellenállásokat használva. Bár ennek vannak veszélyei, cserébe könnyen letiltható lehet pl az adott gombok lenyomásából származó változás (később jól fog jönni) A két nyomógomb az állításhoz nálam a Mega panel esetén az 50-51-es lábhoz lett konfigurálva.
3. Az ébresztő leállítására az ext shield panelen is rajta lévő 3-as megszakítás lábon lévő gombot használtam.

Pár dolog amit még tovább kell fejleszteni, nincsen teljesen kész:

1. A másodperc jelenleg semmilyen szín alatt nem állítható, nullázható, ez egyelőre kimaradt, pedig fontos lehet pontos idő beállításánál. És ad egy problémát is jelenleg: azt a másodpercnyi időt, amennyi ideig végezzük a beállításokat hozzáadja a beállított időhőz képest. Azaz beállítok mondjuk 10.10 percet, de ha a beállítás eltartott 80 másodpercig, akkor már a megjelenő idő 10.11 lesz, mert átbillent egyszer a perc. Azaz a másodperccel van még mit kezdeni.
2. A milis() túlcsordulása sincsen még lekezelve, ez kb 4 sort igényel, hogy a túlcsordulás esetén az óra ugyanonnan folytassa, ahonnan előtte volt.
3. Az ébresztőóra állítást és a pontos idő állítást külön kell vennem, ne egybe történjen. Ehhez kell egy újabb nyomógomb, és nagyon minimális változtatás /átszervezés a progiban.
4. Ugyanígy az értékek fel-le léptetését is meg lehet oldani, jelenleg csak felfelé tudunk léptetni, és körbe kell forgatni, ha kisebb értéket szeretnénk beállítani. Ehhez kell egy plusz nyomógomb, és még egy lefele léptető rutin. Bár végülis így is működik.
5. Az LCD háttérvilágítást is lehet kapcsolgatni fogom, mert minek menjen, meg energiatakarékosság. Csak adott esetekben kell világítania (pl ébresztés, állítás). Végülis csak egy hordozható óra lesz :-).
6. Ha a fentieket megcsinálom, akkor azt hiszem neki kell állni az optimalizálásnak, mert sokallom a méretét. Látok benne lehetőséget, de drasztikusat annyira nem 10-15% körülit, ez az én tudatlanságom oka valószínűleg.
De ezek csak a következő napokban, most 2-3 napra félre kell sajnos tennem :-(

És amit még szeretnék:
- soros porton PC-ről kiküldött órát és ébresztőt fogadni, annak megfelelően beállítani (első érzésre ez jelentős kódnövelő tényező lesz..... Legalábbis ha byte-onként az üzeneteket fel kell dolgoznom)
- belevenni a naptárt is, ez egy nagyobb falat......

Ezt azthiszem már csak hétvégén.
Claude
Újonc
Újonc
Hozzászólások: 3
Csatlakozott: 2013. április 6. szombat, 14:35

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

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

Üdv. Mindenki!
Segítséget szeretnék kérni, mivel nem tudom életre kelteni az Ext1 panelen keresztül az LCD kijelzőt. A megírt mintaprogramot ellenőrzés után feltöltöm az Uno alaplapra, majd a kijelző kétszer felvillan rövid ideig, elsötétül és ez után csak a háttérvilágítást lehet látni. A feltöltést 0023 illetve az 1.6 programokkal is végrehajtottam, mindkét esetben azonos eredménnyel.
Üdvözlettel.
Claude
Újonc
Újonc
Hozzászólások: 3
Csatlakozott: 2013. április 6. szombat, 14:35

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

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

Üdv. Mindenki!
Az LCD működési problémámat az Ext1 panelen egy kiadós alvás és gondolkozás után sikerült megoldani. A contrast potmétert majdnem kiindulási helyzetbe (kb. 2 ohm) állítva megjelent az üzenet. A program szépen működik.
Avatar
djusee
DrótVégénSzéndarab
Hozzászólások: 45
Csatlakozott: 2009. április 18. szombat, 6:00

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

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

Sziasztok.
Nagynehezen van egy kis idöm foglalkozni a programozással ugyhogy elkezdtem a tanfolyamot ami nagyon szimpatikus.
17. leckénél a házit megoldottam a magam modján, kicsit szégyenkezve teszem fel :oops:

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

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


/* Hazi feladat Orat csinalni, 12 tol kezd, lcd re kiirja
es szamolja hanyszor lett beinditva
*/
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

byte ora = 12;
byte perc = 0;
byte mperc = 0;
byte mpercold = 0;
byte inditas = 0;
byte takt = 0;
byte oldtakt = 0;

void setup()
{
  inditas = EEPROM.read(1);//EEprom bol kiolvas
  inditas ++;// inditas valtozohoz hozzaad 1 et
  EEPROM.write (1, inditas);// majd ezt beirja az EEpromba
  lcd.begin(20, 4);
  lcd.print("Ossz. inditva:");
  lcd.print(inditas);// kiirja az inditas valtozo erteket
}

void loop()
{
  takt = millis()/1000; //masodpercenkent valtozik
if (takt != oldtakt){ // ha elmult 1 mperc akkor
 oldtakt = takt; // oldtakt valtozo felveszi a takt erteket
  mperc ++; // masodpercet 1 el novelem
}
if (mperc > 59){ //1 perc elmult
  mperc = 0;
  perc ++;
  lcd.setCursor(0,1);
  lcd.print("        "); // torlom a sort
}
if (perc > 59){ // 1 ora elmult
  perc = 0;
  ora ++;
}
if (ora > 23){ // 1 nap elmult
  ora = 0;
}
if (mperc != mpercold){ // masodpercenkent tortenjen kiiras
  mpercold = mperc;
  lcd.setCursor(0,1);
  lcd.print(ora);
  lcd.print(":");
  lcd.print(perc);
  lcd.print(":");
  lcd.print(mperc);
}
}
Igen az inditas csak 255 ig fog mutatni utána túlcsordul, de nem zavar egyenlöre és az LCD kezelésnél van gondom hogy a 00:00:00 ával tudjam kiiratni a számokat.
De járható út ez vagy másik megvalósitást kellene kigondolnom? Már töprengek hogy remek kis munkaóra számlálót lehetne csinálni belöle a generátoromhoz.Mondjuk majd egy kis ADC zés után még teljesitményt is tudna kiirni esetleg jelezne ha eljött az ideje a filter cserének, olaj cserének... reménytelen álmodozó vagyok. :)
Köszönöm
Avatar
djusee
DrótVégénSzéndarab
Hozzászólások: 45
Csatlakozott: 2009. április 18. szombat, 6:00

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

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

Hello.
Változtattam a kódon, igy mostmár kiirja a 00:00:00 át és felhasználtam az EEPROM irást is amit elöbbi leckében kaptam. Igaz kicsit mégtöbb lett az if és nemtudom mennyire lassitja még a több kurzor mozgatás, illetve melyiket a gyorsabb ellenörizni a (<=) vagy a (>)? Vagy ezek nem lassitják nagyon a ciklust? :oops:
Sajnos egyenlöre másképp nemtudom megoldani.

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

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


/* Hazi feladat, orat csinalni, 12 tol kezd, lcd re kiirja
es szamolja hanyszor lett beinditva
*/
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

byte ora = 12;
byte perc = 0;
byte mperc = 0;
byte mpercold = 0;
byte takt = 0;
byte oldtakt = 0;
byte inditasHigh; // EEPROM felso byte
byte inditasLow; // EEPROM also byte
word inditas; // inditas ertek valtozo, kijelzesre

void setup()
{
  inditasHigh = EEPROM.read(2);//EEPROM bol kiolvas,felso byte
  inditasLow = EEPROM.read(1);//EEPROM bol kiolvas,also byte
  inditas = word(inditasHigh,inditasLow);// wordre alakitja
  lcd.begin(20, 4);
  lcd.print("Ossz. inditva:");
  lcd.print(inditas);// kiirja az inditas valtozo erteket
  lcd.setCursor(2,1);
  lcd.print(":");
  lcd.setCursor(5,1);
  lcd.print(":");
  inditas ++;// inditas valtozohoz hozzaad 1 et
  inditasHigh = inditas/256;//osztas egesz szamot tarolja
  inditasLow = inditas%256;//maradekkepzes,modulo,maradekot tarolja
  EEPROM.write (1,inditasLow);// majd ezt beirja az EEPROM ba az also byte ot
  EEPROM.write (2,inditasHigh);// es a felso byte ot
}

void loop()
{
  takt = millis()/1000; //masodpercenkent valtozik
if (takt != oldtakt){ // ha elmult 1 mperc akkor
 oldtakt = takt; // oldtakt valtozo felveszi a takt erteket
  mperc ++; // masodpercet 1 el novelem
}
if (mperc > 59){ //1 perc elmult
  mperc = 0;
  perc ++;
}
if (perc > 59){ // 1 ora elmult
  perc = 0;
  ora ++;
}
if (ora > 23){ // 1 nap elmult
  ora = 0;
}
if (mperc != mpercold){ // masodpercenkent tortenjen kiiras
  mpercold = mperc;
  if (mperc <= 9){
 lcd.setCursor(6,1);
 lcd.print("0");
 lcd.print(mperc); 
} else {
  lcd.setCursor(6,1);
  lcd.print(mperc);
}
  if (perc <= 9){
 lcd.setCursor(3,1);
 lcd.print("0");
 lcd.print(perc); 
} else {
  lcd.setCursor(3,1);
  lcd.print(perc);
}
if (ora <= 9){
 lcd.setCursor(0,1);
 lcd.print("0");
 lcd.print(ora); 
} else {
  lcd.setCursor(0,1);
  lcd.print(ora);
}

}
}
KissGe
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2016. január 3. vasárnap, 20:06

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

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

Sziasztok!

A segítségeteket szeretném kérni, véleményetek szerint a következő kód alapján miért késik jelentősen az órám? :cry:
A jelentős alatt óránként értek akár 2 mp-et is.

Az utasítások végrehajtási idejéből ez nem fakadhat, nem látok olyan buktatót, ami miatt a jelenség fennáll.

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

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

LiquidCrystal lcd(4,5,6,7,8,9);

byte bekapcsolasH;
byte bekapcsolasL;
word bekapcsolas=0;

byte ora;
byte perc;
byte mp;

byte ORA=18;
byte PERC=32;
byte MP=15;
unsigned long start_time;
unsigned long start_time_check=0;

byte tulcsordulas;

byte kijelzonulla=0;

void setup() {
start_time = millis();

ora = ORA;
perc = PERC;
mp = MP;

lcd.begin(16,2);
analogWrite(13, 60);

bekapcsolasH = EEPROM.read(2);
bekapcsolasL = EEPROM.read(1);
bekapcsolas = word(bekapcsolasH, bekapcsolasL);
lcd.print("Futas: ");
lcd.print(bekapcsolas);

bekapcsolas += 1;
bekapcsolasH = bekapcsolas / 256 ; 
bekapcsolasL = bekapcsolas % 256;
EEPROM.write(1, bekapcsolasL);
EEPROM.write(2, bekapcsolasH);
}

void loop() {
  if (start_time + 1000 == millis()) {
    start_time += 1000;
  
    kijelzonulla ++;
    if (kijelzonulla == 10) {
      lcd.setCursor(0,0);
      lcd.print("Pontos ido:");
    }
  
    if (start_time_check > start_time) {
      tulcsordulas++;
      mp +=1;
    }
    
     start_time_check = start_time;
     
    mp += 1;
    if (mp == 60) {
      mp = 0;
      perc +=1;
    }
    if (perc == 60) {
      perc = 0;
      ora +=1;
    }
    if (ora == 24) {
      ora = 0;
    }

     if (ora < 10) {
      lcd.setCursor(0,1);
      lcd.print("0");
      lcd.setCursor(1,1);
      lcd.print(ora);
     }
      else
     {
      lcd.setCursor(0,1);
      lcd.print(ora);
     }
    
     lcd.setCursor(2,1);
     lcd.print(":");

     if (perc < 10) {
      lcd.setCursor(3,1);
      lcd.print("0");
      lcd.setCursor(4,1);
      lcd.print(perc);
     }
     else
     {
      lcd.setCursor(3,1);
      lcd.print(perc);  
     }

     lcd.setCursor(5,1);
     lcd.print(":");

     if (mp < 10) {
      lcd.setCursor(6,1);
      lcd.print("0");
      lcd.setCursor(7,1);
      lcd.print(mp);
     }
     else
     {
      lcd.setCursor(6,1);
      lcd.print(mp);
     }
  }
}
Köszönöm szépen előre is!
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

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

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

A loop futásideját érdemes lenne lemérned. Az elején elmented a microsec() értéket, aztán a végén pedig kiszámolod a pillanatnyi és a mentett különbségét.
Ha ezt halmozod egy változóban, akkor egy óra elteltével kiderül, hogy a halmozott idők milyen összefüggésben állnak a tapasztalt késéssel.
KissGe
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2016. január 3. vasárnap, 20:06

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

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

Köszönöm SzLacus, nem volt rossz ötlet! :)

A helyzet viszont az, hogy 10 percig vizsgáltam a "loop" -ot, a fő elágazás 600 mp alatt mindösszesen 3,2 mp -et vett igénybe, így kizárt dolog, hogy műveleti idő túllépés miatt hagyjon ki egy másodpercnyi idő eltolódást.

Kiegészítettem az órámat egy dátum kijelzéssel, valamint optimalizáltam az idő kijelzést (nem pozicionálom sűrűn a kurzort), meglátjuk, ez mit eredményez.
Válasz küldése