Szélsebességmérő

Tartalom:

  • Forgólapátos szélsebességmérő működése, átalakítása reed relés kontaktus jeladásról hall szenzoros jeladásra
  • Szélsebesség jellemző paraméterei
  • Pillanatnyi szélsebesség, széllökés, átlagos szélsebesség és szeles időtartam meghatározási algoritmusa
  • Megvalósítás Arduino nano-val és 16×2 karakteres LCD kijelzővel, teljes forráskód
  • Megvalósítás áramkör szimulátorban, szimulációs állományok

Kezdetben nem szándékoztam külön „dedikált” szélsebességmérőt készíteni, csak a szélcsend, szellőcske és erős szél fokozatok megkülönböztetését terveztem az automata locsolórendszeremhez. Ha ugyanis erősen fúj a szél, gyorsabban szárad a talaj és gyakrabban kell locsolni. Vásároltam egy szélkereket, és kísérletezgetni kezdtem vele. Közben történt egy szerencsétlen esemény, kiderült, hogy szélsebességmérő reed reléje, vagy annak elhelyezése hibás. Eleinte két kontaktus jelet adott egy fordulatra. Aztán az egyik alkalommal már csak egyet. Elkezdtem alaposabban megnézni, és kiderült, hogy időnként hármat. Ha megütögettem, akkor ismét csak kettőt. Végül arra következtettem, hogy eredetileg kettő volt a szándék, csak a mágnest túl távolra építették be, és időnként a „térerő” akkor is elereszti a reed kontaktusokat, amikor nem kellene. Arra az elhatározásra jutottam, tekintve hogy a reed relé élettartama is korlátozott, hogy hall szenzorra cserélem. Meg is rendeltem, és amíg várakozok az alkatrészre, volt időm elgondolkodni, hogy mit is várok a szélsebesség mérő berendezéstől. Rájöttem, hogy nem is egyszerű dolog megfogalmazni az elvárásaimat. Olyan adatokra lenne szükségem, ami jellemzi a szél tulajdonságait, és később felhasználható lesz a locsolórendszeremhez. Hosszas gondolkodás után a következő adatokat, információkat tartottam hasznosnak:

  1. Pillanatnyi szélsebesség. Ezt nem is olyan egyszerű mérni ezzel a szélkerékkel, mert egy kisebb szellőcske éppenhogy csak forgatja a kereket, ami egy fordulat alatt két kontaktus jelet ad. Rögvest felmerül a kérdés, hogy mit tekintek szélcsendnek. Önkényesen úgy döntöttem, 5 másodperc lesz a határ. Ha 5 másodperc alatt egyetlen jelet sem kapok, akkor az szélcsend. Közben persze lehet, hogy a szélkerék megmozdul, de kevesebb mint fél fordulatot tesz, vagy hosszabb mint 5 másodperc alatt ad kontaktusjelet, de ezt már nulla sebességnek tekintem. Mindazonáltal a pillanatnyi szélsebességnek nincs túl nagy jelentősége. Ha nagy orkán fúj, akkor esetleg érdekes lehet tudni, mekkora volt a szél egy adott pillanatban. Azonban teljes szélcsendben egy madár szárnycsapása is szélvihart okozgat, így ez tényleg csak „érdekes” adat, de nem sok mindenre jó.
  2. Széllökés. Szerintem a pillanatnyi szélsebesség nem hasznos, és a szél természetéről többet árul el a tartós légmozgás. Nehezen döntöttem el, hogy mennyi is a „tartós”! Végül úgy gondoltam 10 másodperces légmozgás már tényleg szél, így ekkora időegységben a levegő mozgását már szélnek tekintem. Azonban ez az időegység még mindig nem sokat árul el, így ezt széllökésnek neveztem el, és locsolórendszeremhez nem fog használható adatot szolgáltatni, csupán érdekesség. Ennek már a maximumát is érdemes megjegyezni.
  3. Átlagos szélsebesség. Nagy kérdés, hogyan is átlagoljak. Ha egy teljes napot vennék alapul, az nem biztos, hogy értelmezhető információt ad. Pl. ha egy órát fúj a szél 10 km/h-val, aztán a fennmaradó 23 órában beáll a teljes szélcsend, akkor az átlag kb. 0,4 km/h, ami elhanyagolható, mintha nem is fújt volna a szél. Ezért arra gondoltam többet mond, ha csak arra az időre átlagolok, amikor fújt a szél.
  4. Szélfújás időtartama egy nap alatt. Ha az előző pont szerint az átlag szélsebességet a szeles időszak idejére akarom képezni, akkor mérnem kell azt az időtartamot, amikor fújt a szél. Értelmes adat természetesen a szélcsend időtartama is.

Sajnos az átlagsebességek, maximum értékek meghatározásakor választanom kell egy törlési időpontot, amikor újra indítom az értékek meghatározását. Ez logikusan minden nap éjfél lehetne. Ekkor azonban időmérés is szükséges. Nagy dilemma, hogy megéri-e ezért egy RTC óra modult beépíteni. Úgy döntöttem, hogy nem (épp nincs felesleges óra modulom, így ez könnyű döntés volt). Azonban az Arduino tartalmaz egy viszonylag pontos órajelet, tehát az éjfél meghatározása nem lehetetlen. Olyan megoldást választottam, ami szerint percenként növelek egy változót, és ha ez elérte az 1440-et (24 óra telt el), akkor a változó értékét nullázom az összes tárolt szélsebesség adattal együtt. Azonban biztosítani kell valahogyan, hogy ez a nullázás pont éjfélkor legyen. Ehhez csináltam a programban egy óra beállító programrészt. Az éjfél óta eltelt időt ebből a változóból könnyű kiszámolni és folyamatosan kiírni a képernyőre. Már csak azt kellett megoldani, hogy az éjfél óta eltelt percek számát valahogyan be lehessen állítani. Szerintem elég kényelmes megoldást sikerült megvalósítani, egyetlen nyomógombbot használok ehhez. Nagy ellenséggé vált az áramszünet, mert minden alkalommal be kell utána állítani az órát. Mégsem tökéletes megoldás, de szegény ember vízzel főz. A nyomógombot másra is használom, mert segítségével a sokféle mérési eredményt lehet sorban megjeleníteni az igen kicsi méretű 2×16 karakteres LCD kijelzőn. Nagyobb kijelzőt egyenlőre nem akartam pazarolni erre a feladatra.

Végül a program a következőket valósítja meg: méri a szélsebességet egy fordulat ideje alapján, méri a fenti definíció szerinti széllökést, megjegyzi ennek maximumát, amit éjfélkor nulláz. A körbe forgások kontaktusjeleiből meghatározza a szeles időtartamot, amit szintén éjfélkor nulláz. A szeles időtartamból és a kontaktusszámból adódik egy osztással az átlagsebesség, ami nyilvánvalóan azzal az időtartammal együtt értelmezhető, mikor fújt a szél. Pl. ha az átlag szélsebesség 10 km/h, és aznap 24 órán át fújt a szél, akkor ez egy szeles nap volt. Ha az átlag sebesség 10 km/h de aznap csak 10 percig volt szélfújás, akkor ez a nap valójában szélcsendes volt. Tehát az adatokat értelmezni kell. Ez a szoftver láthatóan mellőzi a mesterséges intelligenciát. Ezért is teszem közzé ingyen, értéke a szélcsendes nap átlagsebességéhez konvergál. Tehát nulla!

Az alábbi példa program még nem működik végleges megoldásként. Ez egy „deszka” modell. Ténylegesen működik, hajszárító szélsebességét méri, de még nem szolgáltat adatokat valós szélsebességekről. Ehhez meg kell várni a hall szenzorokat, azok beépítését, és azt, hogy legyőzzem tériszonyomat és felmásszak a tetőre.

Azonban a működőképesség tesztelt, talán lényegi hibák sincsenek benne. A működési elve kicsit hasonlít a prellmentesítésnél ismertetett harmadik mintapéldában olvasható megoldásra. A millis() függvényt használom, ami a mikrovezérlő elindítása óta eltelt milliszekundumokat adja vissza. Azt hiszem ez egy olyan memória változó, amit egy ezred másodpercenként keletkező belső megszakítás növel. Ez „atombiztosan” minden ezred másodpercben megtörténik, így lehet rá alapozni. Azt nem tudom, hogy ha megszakításokat használnék, akkor kihagyná-e a számlálást a vezérlő, de nem használok megszakítást. Mivel a a változó által visszaadott értéket figyelem, nem kritikus az egyes programrészek végrehajtása, sehol nem használok delay() függvényt. Illetve egy helyen, az órabeállításnál használok, de ott semmi más nem működik a sebesség mérés sem. Nem kell passzióból naponta többször is időpontot állítgatni, és minden rendben lesz. Ezzel a technikával minden párhuzamosan zajlik, figyelem a nyomógombot (prellmentesítem), figyelem és feldolgozom a szélkerék kontaktus adatait, mérem az eltelt időt, még az LCD háttérvilágítását is időzítem, ne világítson egész nap. Mindez egyszerre, és semmi nem nem marad ki.

Megmértem az óra pontosságát is. Meglepően pontos volt. A mobiltelefonomhoz állítottam az időpontot, és megnéztem egy nap múlva. Szemmel nem tért el egyetlen másodpercet sem. Nem kritikus az, hogy pont éjfélkor nullázza a program a gyűjtőket, így elég lesz havonta beállítani az időt, kivéve, ha áramszünet lesz. A program egy LCD kijelzőn kijelzi a mért és számított adatokat. Egyetlen nyomógombbal lehet váltani, hogy a kijelzőn mit jelezzen ki. Néhány fotó:

Bocs a minőségét, az LCD az Arduino UNO-ről kapta a tápot (az meg a PC-ről), és ilyenkor a kontraszt nem tökéletes. Ráadásul a fejlesztő panelemen csak 4 soros LCD van, de úgy írtam meg a programot, hogy 2×16-os kijelzőn működjön. A 2×16-os kijelző esetén a kijelző címét át kell állítani a harmadik rogramsorban!!

Az LCD háttérvilágítása gombnyomásra bekapcsol, és egy percig világít az utolsó nyomógomb lenyomás után. A kijelző tartalmát csak akkor lépteti a nyomógomb, ha világít a kijelző. Amikor a program az időt jelzi ki, a nyomógomb folyamatos nyomva tartásával lépteti az órák illetve percek értékét, és azt állítja be órának illetve percnek, amit a a nyomógomb elengedésekor látunk a kijelzőn. Az óra beállítást értelem szerűen két lépésben lehet elvégezni, először az órákat (0-24-ig) illetve egy gombnyomással átváltunk a percek beállító képernyőre, és ekkor állíthatjuk be a perceket (0-59-ig).

És íme a forráskód:

#include <Wire.h>    //I2C library 
#include <LiquidCrystal_I2C.h>  //I2C LCD kezelő könyvtár
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  //LCD paraméterek megadása, a 4 soros LCD-m címe 3F

bool elozo;                        //segéd változó előző szélkerék kontaktus állapot tárolására
bool most;                         //segéd változó a pillanatnyi szélkerék kontaktus állapot tárolására        
long ido_tmp=millis();             //segéd változó egy fordulat idejének a méréséhez
long nemforog_ido=millis();        //segéd változó amivel mérjük az időt akkor, ha nincskontaktus, mert nem fúj a szél
long szelkerek_ido=millis();       //segéd változó, amivel a szélkerék pillanatnyi sebesség frissítés 1 másodperces idejét mérem
long ido_tmp_10=millis();          //segéd változó, amivel a 10 másodperces széllökés méréshez használok
long kijelzo_valtas_ido=millis();  //segéd változó, amit a 1 másodperces kijelző tartalom frissítéshez használok
bool frissit=true;                 //true értéke esetén azonnal befrissíti a kijelző érékét, ha false akkor csak másodpercenként
long percidozito=millis();         //segéd változó az egy perces időzítéshez, percenként növeljük az ejfel változó értékét
byte adat_index=0;                 //az éppen aktuálisan kijelzett adat indexe. Minden ciklusban 1-el növelem, 7 után nullázom
byte ora;                          //segéd változó a szeles és szélmentes órák kiírásához, és az idő beállításhoz
byte perc;                         //segéd változó a szeles és szélmentes percek kiírásához, és az idő beállításhoz
long nyomva_ido=millis();          //setup gomb nyomvatartásának figyeléséhez a prellmentesítés érdekében 50msec időzítéshez
long elenged_ido=millis();         //a nyomógomb elengedési idejének figyeléséhez a prellmentesítés érdekében 50msec időzítéshez
bool nyomva;                       //nyomógom nyomva jelzésére, prellmentesítéshez kell
bool elengedve;                    //nyomógomb elengedve jelzésére, prellmentesítéshez kell
bool setup_mod;                    //ezzel jelzem, ha megnyomta a nyomógombot, és elkezdődik a setup folyamat (kijelzett érték beállítás, idő beállítás)
long vilagitas_ido=millis;         //az lcd kijelző háttérvilágításának időzítésére használom. bármilyen gombnyomástól számított
                                   //60 másodperccel kikapcsol a kijelző háttérvilágítása 
bool lcd_vilagitas;                //ez jelzi, hogy az lcd kijelző háttérvilágítása be van kapcsolva, vagy ki van kapcsolva
byte imp=0;                        //ezt a második felfutóél jelzésére használom, hogy egy fordulat idejét tudjam megmérni
int imp_10sec=0;                   //a 10 sec alatt beérkezett impulzusok száma
long imp_atlag=0;                  //az egy nap alatt beérkezett impulzuok száma a napi átlagsebesség méréshez
int ford_ido=0;                    //egy fordulat idejét milisecundumban, pillnatnyi sebesség méréséhez
bool all=false;                    //ez a változó jelzi, ha áll a szélkerék és nem kell kiszámolni a pillanatnyi szélsebességet, mert éppen nulla
float pill_szelseb=0;              //két impulzus közt eltelt időből kiszámított pillanatnyi szélsebességet
float napi_atlag_seb=0;            //napi átlag sebesség, amit a napi impulzusszámból és a szeles idő másodpercekben mért értékéből számolok ki
float szellokes;                   //a széllökés 10 másodpercre számított értéke
float szellokes_max;               //a széllökés maximumát tárolja. Naponta egyszer kel nullázni, és így kezdődik minden nap éjfélkor a maximum meghatározása
                                   //Az éjfélkor történő nullázásról egy ejfel navű változó gondoskodik, ami 1440-nél nullázódik. 1440 perc van egy nap
                                   //ez így nem valódi pontos óra, a processzor kavarcz órajelén alapul, nem túl pontos, időnként be kell állítani
int szeles_ido=0;                  //A szeles idő másodpercben mért értéke a nap során
int szel_mentes_ido;               //a szélmentes idő másodpercben mért értéke a nap során
int ejfel=0;                       //az éjfél óta eltelt idő percekben


void setup() {
  Serial.begin(9600);
  Serial.println("Indul...");
  pinMode(2,INPUT);            //2-es kivezetésre kötöttem a kontaktus jelét             
  digitalWrite(2,HIGH);        //felhúzó ellenállás bekapcsolása    
  elozo=digitalRead(2);        //máris vezünk egy mintát a bemenetből
  pinMode(3,INPUT);            //3-es kivezetésre kötötjük a nyomógombot             
  digitalWrite(3,HIGH);        //felhúzó ellenállás bekapcsolása    
  lcd.begin(20,4  );           //LCD inicializálása
  lcd.clear();
  lcd.backlight();             //háttérvilágítás bekapcsolása
  lcd_vilagitas=HIGH;          //ezzel jelezzük, hogy világít a háttérvilágítás, csak akkor lépteti a program a kijelzett adatot
                               //a képernyőn, ha világít a háttérvilágítás (az első gombnyomás 60 másodpercre bekapcsolja)
}

void loop() {
  /***********************************************************************************************************
   * Ezek a programrészek a szélsebességmérő kontaktusait figyelik, és mérik a forgási időt, kontaktusszámot *
   * és az eredményeket elhelyezik a megfelelő változókban.                                                  *
   **********************************************************************************************************/
  most=digitalRead(2);             //a pillanatnyi kontaktus állapot beolvasása
  if(elozo==LOW and most==HIGH) {  //felfutó él
    nemforog_ido=millis();         //minden kontaktusnál elindítjuk a nemforgás időzítőt, 5 másodperc múlva tekintjük úgy, hogy áll a szélkerék
    all=false;                     //forog a szélkerék
    imp_10sec++;                   //10 másodperces impulzus számláló növelése
    imp_atlag++;                   //napi impulzusszámláló növelése
    if (imp==0) {imp++;}           //egy fordulat idejének meghatározásához két impulzust kell leszámolni, ez volt az első
    if (imp==1) {ford_ido=millis()-ido_tmp;ido_tmp=millis();imp=0;} //megvolt a második impulzus, az egy fordulat idejének kiszámolása
                                                                    // időpillanat változó törlése következő méréshez
  }
  elozo=most;
  
  if (millis()>nemforog_ido+5000) {                             //ha 5 másodperc alatt sem ad egyetlen impulzust sem, akkor úgy tekintjük nulla a szélsebesség
    imp=0;
    pill_szelseb=0;
    all=true;
  }
  
  if (millis()>ido_tmp_10+10000) {                              // 10 másodpercenként nullázom az imp_10sec változót, kiszámolom a széllökést és tárolom a maximumát
    napi_atlag_seb=(((float)(imp_atlag)/2)*2.5)/szeles_ido;     //napi átlag a napi impulzusszámból és a szeles (amikor forog a kerék akkor növeljük másodpercenként) 
                                                                //másodpercek számából
    szellokes=((float)(imp_10sec)/20)*2.5;                      //10 másodperces széllökés értékének frissítése
    if (szellokes_max<szellokes) {szellokes_max=szellokes;}     //széllökés maximum frissítése
    imp_10sec=0;                                                //újra kezdjük a 10 másodperc alati impulzusok mérését
    ido_tmp_10=millis();                                        //elkezdődik a 10 másodperc mérése ezzel a kezdőértékkel
  }
  
  if (millis()>szelkerek_ido+1000) {                              //egy másodpercenként frissítem a pillanatnyi szélsebesség értékét,  
                                                                //ha éppen az időt állítjuk be, akkor nem  számoljuk az impulzusokat, mert ott delay() van!
    if (!all) {                                                 //nem áll a szélkerék, lehet sebességet számolni
      pill_szelseb=2.5*(1000/(float)ford_ido);                  //pillanatnyi szélsebesség kiszámítás egy körülfordulás idejéből
      szeles_ido++;                                             //növeljük a szeles idő idejét másodperc alapon mérő számlálót az átlag sebesség meghatározáshoz
    }
    else {szel_mentes_ido++;}                                   //növeljük a szélmentes idő értékét 1 másodperccel (áll a szélkerék)
    szelkerek_ido=millis();                                       //innen indul egy új egy másodperces időzítés
  }

   
  if (ejfel>=1440) {imp_atlag=0;szeles_ido=0;ejfel=0;}           //24 óra elteltével nullázzuk a napi impulzusgyüjtőt és a napi szeles idő változóját, és 
                                                                //újra indul az ejfel szamlaló, ami percenként növekszik. 24 óra 1440.

  if (millis()>percidozito+60000) {                             //egy percenként növeljük az ejfel változót
    ejfel++;                                                    
    percidozito=millis();
  }

  /*************************************************************************************************************************************
   * Az itt következő programrészek a nyomógombot figyelik. Megtörténik a prellmentesítés. Mivel a hosszú megnyomásnak                 *
   * szerepe van, a nyomógomb elengedés indítja az akciókat. Egy megnyomás bekapcsolja a háttérvilágítást (ez a nyomógomb lenyomással  *
   * törtéik nem az elengedéssel). Ha már világít a háttérvilágítás, akkor növeljük a kijelzett adat indexértékét. Ha hosszan          *
   * nyomvatartjuk az időkijelzés óra és perc felirattal jelzett állapotában, akkor az óra illetve a perc értékét növeli               *
   * ciklikusan, ha elérte a 23-at (óra) illetve az 59-et (perc), akkor 0-ról indul újra. Ha egy ilyen bállítás után                   *
   * elengedjük a gombot, akkor ezzel be is állítottuk az órát.                                                                        *
   *************************************************************************************************************************************/
  //megnyomta a nyomógombot, de még lehet, hogy prelles
  if (digitalRead(3)==LOW and nyomva==LOW) {    //megynomta a setup gombot
    nyomva_ido=millis();  //prellmentesítéshez ezzel indul az 50msec időzítése
    nyomva=HIGH;  //innen tudjuk, hogy már történt egy kontaktus, 50 msec múlva már biztosan prellmentes
    lcd.backlight();vilagitas_ido=millis();   //bekapcsoljuk a háttérvilágítást, és elindítjuk a kikapcsolási időzítést
                                          //lcd_vilagitas változót még nem billentjük be, az fogja jelezni később, hogy lehet léptetni 
                                          //a kijelzett adat indexét

    }    
  //ha 50msec mulva is nyomva tartja,akkor ez már nem prelles, biztosn nyomva van, lehet belépni a setup folyamatba
  if (digitalRead(3)==LOW and millis()>nyomva_ido+50 and nyomva==HIGH) {setup_mod=HIGH;}       //mar itt is lehetne növelni a kijelzett adat index értékét
                                                                                               //de az óra beállítás miatt az elengedéskor növelek (ha már 
                                                                                               //bilágít a háttérvilágitás, mert ha nem akkor csak azt bekapcsolom)
                                                                                               //ha 1 másodpercnél tovább nyomom, és nem az órabeállításban vagyok
                                                                                               //akkor nem fog történni semmi
  //elengedte a nyomógombot, de még lehet, hogy prelles
  if (digitalRead(3)==HIGH and elengedve==LOW and nyomva==HIGH) {elenged_ido=millis();elengedve=HIGH;}
  //már 50msec óta elenged, biztosan nem prelles, beállítási értéket váltunk, lehet várni az új megnyomásra
  if (digitalRead(3)==HIGH and elengedve==HIGH and millis()>elenged_ido+50)                    //amikor elengedjük a nyomógombot, akkor váltjuk a kijelzett értéket
                                                                                               //Ha azonban nem világított a háttérvilágítás, akkor ez a gombnyomás
                                                                                               //csak bekapcsolja azt, és nem léptet 
  {
    nyomva=LOW;
    elengedve=LOW;
    Serial.println(lcd_vilagitas);
    if (lcd_vilagitas==LOW) {lcd_vilagitas=HIGH;}  //ezzel elnyeljük az első nyomógomb lenyomást, ha nem világított a háttérvilágítás (csak bekapcsoljuk azt)
    else {                     //már világit a háttérvilágítás, lehet az adatindexet növelni
      adat_index++;
      if (adat_index>7) {adat_index=0;}            //a legutolsó adat után újra a legelső adatot fogjuk kiírni
      frissit=true;                                //azonnal frissíteni kell a képernyőt, mert gombnyomás történt
      vilagitas_ido=millis();                          //innen indul a 60 másodperc időzítés a háttérvilágítás kikapcsolására
    }
  } 

  if (millis()>vilagitas_ido+60000)   //ha 60 másodperce nem nyúlt a nyomógombhoz akkor a háttérvilágítást kikapcsoljuk 
  {
    lcd_vilagitas=LOW;
    lcd.noBacklight();
  }

  if (digitalRead(3)==LOW and setup_mod==HIGH and nyomva==HIGH and millis()>nyomva_ido+1000)   //egy másodpercig nyomvatartotta, változtatjuk az óra vagy a perc értékét
                                                                                               //elengedéskor az éjfél óta eltelt időt már be is állítottuk 
  {
    ora=ejfel/60;                               //ejfel változóból kiszáítjuk az óra értékét
    perc=ejfel-(ora*60);                        //ejfel változóból kiszámítjuk perc értékét
    if (adat_index==6) {                      //ha az éppen kijelzett adat az óra volt, akkor óra értékét fogjuk növelni
      do {
        ora++;if (ora>23) {ora=0;}
        lcd.setCursor(11,1); 
        lcd.print(ora);lcd.print("  ");       //kiírjuk az óra aktuális értékét
        ejfel=ora*60+perc;                    //minden növelési ciklusban kiszámítjuk ejfel értékét
        delay(700);
      } while (digitalRead(3)==LOW);          //addig fut a ciklus, amíg nyomjuk a gombot
    }
    if (adat_index==7) {
      do {
        perc++;if (perc>59) {perc=0;}
        lcd.setCursor(12,1); 
        lcd.print(perc);lcd.print("  ");
        ejfel=ora*60+perc;
        delay(700);
      } while (digitalRead(3)==LOW);
    }
    setup_mod=LOW;                             //kilépünk a setup módból, gombnyomás mentes álapot jut érvénre, frissül a képernyő másodpercenként az aktuálisn kijelzett adattal
    frissit=true;                              //azonnal frissíteni kell a képernyőt, mert változtattunk az idő értékén
    nyomva=LOW;                                //elengedtük a nyomógombot
    percidozito=millis();                      //innen indítjuk az egy perc időzítését az éjfel szamlaló növeléséhez
    vilagitas_ido=millis();                    //innen indul a 60 másodperc időzítés a háttérvilágítás kikapcsolására
  }

  /*******************************************************************************************************************************
   * Ebben a részben a kijelzőn megjelenő adatot frissítjük másodpercenként. Hogy mit lehet látni a kijelzőn azt az adat_index   *
   * változó dönti el, amit a nyomógomb lenyomásokkal tudunk változtatni, növelni 0 és 7 között. A 6. és 7. index érték          *
   * esetén az időt jelezzük ki, és ha ekkor megnyomjuk hosszan a nyomógombot, akkor a perc illetve az óra értéke változtatható  *
   * amit a nyomógomb elengedésekor azonnal frissítünk is.                                                                       *
   *******************************************************************************************************************************/
  if (millis()>kijelzo_valtas_ido+1000 or frissit) {  //két másodpercenként frissítjük a mért értékeket, ha éppen beállítjuk 
                                                                   //az éjfélig hátralévő időt, akkor nem
    frissit=false;  //ettől kezdve már csak másodpercenként frissítünk
    switch (adat_index) {
       case 0:         //pillanatnyi széllsebesség értékének kiírása
        lcd.setCursor(0,0);lcd.print("Pill. szelseb:  ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(pill_szelseb)+5,1);lcd.print(pill_szelseb,1);  //egy tizedesjegy hosszan kiírjuk a pillanatnyi szélsebességet
                                                                              //a kiírás kezdő pozicióját a szélsebesség nagyságrendje határozza meg,
                                                                              //hogy ne vándoroljon a kiírt szám, így a tizedespont egy helyben marad
        break;
       case 1:         //széllökés értékének kiírása
        lcd.setCursor(0,0);lcd.print("Szellokes:      ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(szellokes)+5,1);lcd.print(szellokes,1);
        break;
      case 2:         //széllökés maximum értékének kiírása
        lcd.setCursor(0,0);lcd.print("Szellokes max.: ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(szellokes_max)+5,1);lcd.print(szellokes_max,1);
        break;
      case 3:         //24 órás átlag sebesség (csak a szeles időszakot vesszük figyelmebe)
        lcd.setCursor(0,0);lcd.print("24h atlag seb.: ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(napi_atlag_seb)+5,1);lcd.print(napi_atlag_seb,1);
        break;
      case 4:         //szeles időszak idejének kiírása óra perc kijelzéssel (ennyi ideig forgott a szélkerék)
        ora=szeles_ido/3600;
        perc=(szeles_ido-ora*3600)/60;
        lcd.setCursor(0,0);lcd.print("Szeles idoszak: ");
        lcd.setCursor(0,1);lcd.print("                ");
        lcd.setCursor(7,1);lcd.print(ora);lcd.print("o ");lcd.print(perc);lcd.print("p   ");
        break;
      case 5:         //szelmentes időszak idejének kiírása óra perc kijelzéssel (ennyi ideig ált a szélkerék)
        ora=szel_mentes_ido/3600;
        perc=(szel_mentes_ido-ora*3600)/60;
        lcd.setCursor(0,0);lcd.print("Szelmentes ido- ");
        lcd.setCursor(0,1);lcd.print("szak:           ");
        lcd.setCursor(7,1);lcd.print(ora);lcd.print("o ");lcd.print(perc);lcd.print("p   ");
        break;
      case 6:         //idő kijelzése (ha hosszan nyomjuk a gombot, akkor beállíthatjuk az óra értékét)
        ora=ejfel/60;
        perc=ejfel-(ora*60);
        lcd.setCursor(0,0);lcd.print("Ido:            ");
        lcd.setCursor(6,0);
        if (ora<10) {lcd.print("0");}
        lcd.print(ora);lcd.print(":");
        if (perc<10) {lcd.print("0");}
        lcd.print(perc);lcd.print("  ");
        lcd.setCursor(0,1);lcd.print("Ora beall.:     ");
        break;
      case 7:         //idő kijelzése (ha hosszan nyomjuk a gombot, akkor beállíthatjuk a perc értékét)
        ora=ejfel/60;
        perc=ejfel-(ora*60);
        lcd.setCursor(0,0);lcd.print("Ido:            ");
        lcd.setCursor(6,0);
        if (ora<10) {lcd.print("0");}
        lcd.print(ora);lcd.print(":");
        if (perc<10) {lcd.print("0");}
        lcd.print(perc);lcd.print("  ");
        lcd.setCursor(0,1);lcd.print("Perc beall.:     ");
        break;
    }
    kijelzo_valtas_ido=millis();
  }
  
}

/******************************************************************************************
 * Ez a függvény a kijelzés kezdő poziciójához ad vissza egy eltolási értéket a kijelzett *
 * szám nagyságától függően                                                               *
 ******************************************************************************************/
byte poz_szam(byte adat)  //Az adat változóba beolvasott szám nagyságától függően 0,1,2-t ad vissza a kiírás könnyítéséhez
{
    if (adat<100) {                              //ha kisebb mint 10, akkor kettővel vagy eggyel kell eltolni a számot
      if (adat<10) {return 2;} else {return 1;}  //ha tiznél kisebb akkor eggyel kell eltolni
    } else {return 0;}                           //ha 100-nál nagyobb akkor nincs eltolás
}

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

A napokban megérkezett a hall szenzor. Sajnos rosszat rendeltem, mert reteszelő típust sikerült kiválasztani. Sebaj, ezzel is sikerült előrehaladást elérnem. A Hall szenzorokkal kapcsolatos tapasztalataimról itt olvashatsz részletesebben. Beépítettem az első szenzort. Tökéletesen működött, mindaddig, amig véletlenül fordítva kötöttem rá a tápfeszt. Persze azonnal tönkrement. Ebből okulva, most védelemmel látom el (egy dióda és egy ellenállás), és csak utána cserélem ki a meghibásodott darabot.

Néhány fotó következzen a beépítés mikéntjéről! Így nézett ki a reed relé. A csavarokat már kiszedtem, mikor eszembe jutott, hogy le kellene fotózni:

…és így néz ki az általam beépített hall szenzor (itt már be is ragasztottam):

A hall elemet sugár irányban mozgattam a középponttól kifelé, és azt tapasztaltam, hogy középen a kapcsolgatás kitöltési tényezője kb. 50%, míg a széle felé haladva csökken. Ez a kép a középhelyzetet mutatja:

Azon a ponton, ahol még reagált a hall szenzor, már csak kb. 10% időre kapcsolt a szenzor:

A jelen állapotban természetesen egy kapcsolás egyenlő egy körbefordulással, így a forráskódot is módosítani kell egy kicsit. Ha kicseréltem a szenzor, közzéteszem a forrást.

Ez a videó bemutatja, hogyan reagál a szenzor a szélkerék forgására. Itt még csak egy picika próbaprogram kapcsolgatja a led-et:

Szimulátorban is megépítettem a kapcsolást, könnyedén ki is próbálhatod, ehhez itt találsz leírásokat. A szélsebességmérő szimulációjáról az előbbi linken a 16. feladatban olvashatsz. Látható is, hogy a szimulátor nem teljesen tökéletes, pl. ennek a programnak a szimulálásával vannak problémák. Összességében azonban jól nyomon követhető a működés.


Eltelt jópár hónap! Megérkezett az új típusú hall szenzor (A3144). Ennek a szenzornak a tulajdonsága, hogy a mágneses tér nagyságára érzékeny, és egy adott mágneses fluxus felett billen át. Kibányásztam a régi szenzort, amit sikerült fordított tápfesszel tönkre tenni. Már nagyon óvatos lettem, és a szükséges védő áramkört is megépítettem. Fontos új infó, hogy jóval nehezebb volt a hall szenzor megfelelő elhelyezése. Alig találtam megfelelő pontot, ahol érzékelte a forgó mágnest. Csak akkor érzékelt, ha a szenzor katalógusban megadott érzékelési pontját pontosan a mágnes felé fordítottam. Ez a szenzor felső, függőleges éleinél lekerekített felülete, ahol a feliratok is láthatók:

Ez most éppen egy Y3144 típusú szenzor, aminek más az érzékenysége, de most csak erről találtam fotót a neten! Szóval nagyon nehéz volt jó pozíciót találni. Amikor végre sikerült, gyorsan beragasztottam, és mögé tömködtem a védő áramkört is, amit csak úgy a levegőben építettem meg. Csináltam egy fotót, de nem sok látszik a hall szenzor elhelyezéséből:

Annyit kellene látni, hogy a szélkerék műanyag házának az alján a hall szenzort derékszögben meghajtottam a lábainak tövénél, és lapjával lefele szorítottam a műanyag lemezhez, ami mögött a mágnes forog. Amikor már működött az egész együtt, a védő áramkört is befuttattam ragasztópisztoly műanyagjával. Most kb. 1/3-ad fordulatra húzza le a szenzor a kimenetet 0V-ra. Ha a védőáramkör érdekel, ebben a leírásban találsz róla infót. Egy ellenállás, dióda, zener dióda és kondi az egész! Talán még érdekes lehet a hall szenzor kimeneti jele. Első menetben meg sem mértem, hogy mi jön ki a kimeneten, de utólag eszembe jutott! 5V tápfeszültség esetén (amiből a soros dióda a védőáramkörben levesz kb. 0.6V-ot) az alacsony jel 0.6V, míg a magas kimeneti jelszint 3,6V. Meglepő, hogy a kimenetre kötött 10Kohm ellenállást nem tudja lehúzni 0V közelébe. Ezért ez az érték kicsit túl magasnak tűnik, de szerencsére az Arduino UNO ezt már alacsonynak érzékeli.

És íme az új forrás (alig változott, csak kettő helyett egy jelet kapunk egy körül fordulásra, és ezt kellett javítani):

#include <Wire.h>    //I2C library 
#include <LiquidCrystal_I2C.h>  //I2C LCD kezelő könyvtár
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  //LCD paraméterek megadása, a 4 soros LCD-m címe 3F

bool elozo;                        //segéd változó előző szélkerék kontaktus állapot tárolására
bool most;                         //segéd változó a pillanatnyi szélkerék kontaktus állapot tárolására        
long ido_tmp=millis();             //segéd változó egy fordulat idejének a méréséhez
long nemforog_ido=millis();        //segéd változó amivel mérjük az időt akkor, ha nincskontaktus, mert nem fúj a szél
long szelkerek_ido=millis();       //segéd változó, amivel a szélkerék pillanatnyi sebesség frissítés 1 másodperces idejét mérem
long ido_tmp_10=millis();          //segéd változó, amivel a 10 másodperces széllökés méréshez használok
long kijelzo_valtas_ido=millis();  //segéd változó, amit a 1 másodperces kijelző tartalom frissítéshez használok
bool frissit=true;                 //true értéke esetén azonnal befrissíti a kijelző érékét, ha false akkor csak másodpercenként
long percidozito=millis();         //segéd változó az egy perces időzítéshez, percenként növeljük az ejfel változó értékét
byte adat_index=0;                 //az éppen aktuálisan kijelzett adat indexe. Minden ciklusban 1-el növelem, 7 után nullázom
byte ora;                          //segéd változó a szeles és szélmentes órák kiírásához, és az idő beállításhoz
byte perc;                         //segéd változó a szeles és szélmentes percek kiírásához, és az idő beállításhoz
long nyomva_ido=millis();          //setup gomb nyomvatartásának figyeléséhez a prellmentesítés érdekében 50msec időzítéshez
long elenged_ido=millis();         //a nyomógomb elengedési idejének figyeléséhez a prellmentesítés érdekében 50msec időzítéshez
bool nyomva;                       //nyomógom nyomva jelzésére, prellmentesítéshez kell
bool elengedve;                    //nyomógomb elengedve jelzésére, prellmentesítéshez kell
bool setup_mod;                    //ezzel jelzem, ha megnyomta a nyomógombot, és elkezdődik a setup folyamat (kijelzett érték beállítás, idő beállítás)
long vilagitas_ido=millis;         //az lcd kijelző háttérvilágításának időzítésére használom. bármilyen gombnyomástól számított
                                   //60 másodperccel kikapcsol a kijelző háttérvilágítása 
bool lcd_vilagitas;                //ez jelzi, hogy az lcd kijelző háttérvilágítása be van kapcsolva, vagy ki van kapcsolva
byte imp=0;                        //ezt a második felfutóél jelzésére használom, hogy egy fordulat idejét tudjam megmérni
int imp_10sec=0;                   //a 10 sec alatt beérkezett impulzusok száma
long imp_atlag=0;                  //az egy nap alatt beérkezett impulzuok száma a napi átlagsebesség méréshez
int ford_ido=0;                    //egy fordulat idejét milisecundumban, pillnatnyi sebesség méréséhez
bool all=false;                    //ez a változó jelzi, ha áll a szélkerék és nem kell kiszámolni a pillanatnyi szélsebességet, mert éppen nulla
float pill_szelseb=0;              //két impulzus közt eltelt időből kiszámított pillanatnyi szélsebességet
float napi_atlag_seb=0;            //napi átlag sebesség, amit a napi impulzusszámból és a szeles idő másodpercekben mért értékéből számolok ki
float szellokes;                   //a széllökés 10 másodpercre számított értéke
float szellokes_max;               //a széllökés maximumát tárolja. Naponta egyszer kel nullázni, és így kezdődik minden nap éjfélkor a maximum meghatározása
                                   //Az éjfélkor történő nullázásról egy ejfel navű változó gondoskodik, ami 1440-nél nullázódik. 1440 perc van egy nap
                                   //ez így nem valódi pontos óra, a processzor kavarcz órajelén alapul, nem túl pontos, időnként be kell állítani
int szeles_ido=0;                  //A szeles idő másodpercben mért értéke a nap során
int szel_mentes_ido;               //a szélmentes idő másodpercben mért értéke a nap során
int ejfel=0;                       //az éjfél óta eltelt idő percekben


void setup() {
  Serial.begin(9600);
  Serial.println("Indul...");
  pinMode(2,INPUT);            //2-es kivezetésre kötöttem a kontaktus jelét             
  digitalWrite(2,HIGH);        //felhúzó ellenállás bekapcsolása    
  elozo=digitalRead(2);        //máris vezünk egy mintát a bemenetből
  pinMode(3,INPUT);            //3-es kivezetésre kötötjük a nyomógombot             
  digitalWrite(3,HIGH);        //felhúzó ellenállás bekapcsolása    
  lcd.begin(20,4  );           //LCD inicializálása
  lcd.clear();
  lcd.backlight();             //háttérvilágítás bekapcsolása
  lcd_vilagitas=HIGH;          //ezzel jelezzük, hogy világít a háttérvilágítás, csak akkor lépteti a program a kijelzett adatot
                               //a képernyőn, ha világít a háttérvilágítás (az első gombnyomás 60 másodpercre bekapcsolja)
}

void loop() {
  /***********************************************************************************************************
   * Ezek a programrészek a szélsebességmérő kontaktusait figyelik, és mérik a forgási időt, kontaktusszámot *
   * és az eredményeket elhelyezik a megfelelő változókban.                                                  *
   **********************************************************************************************************/
  most=digitalRead(2);             //a pillanatnyi kontaktus állapot beolvasása
  if(elozo==LOW and most==HIGH) {  //felfutó él
    nemforog_ido=millis();         //minden kontaktusnál elindítjuk a nemforgás időzítőt, 5 másodperc múlva tekintjük úgy, hogy áll a szélkerék
    all=false;                     //forog a szélkerék
    imp_10sec++;                   //10 másodperces impulzus számláló növelése
    imp_atlag++;                   //napi impulzusszámláló növelése
    ford_ido=millis()-ido_tmp;     //egy fordulat idejének kiszámolása
    ido_tmp=millis();             // időpillanat változó törlése következő méréshez 
  }
  elozo=most;
  
  if (millis()>nemforog_ido+5000) {                             //ha 5 másodperc alatt sem ad egyetlen impulzust sem, akkor úgy tekintjük nulla a szélsebesség
    pill_szelseb=0;
    all=true;
  }
  
  if (millis()>ido_tmp_10+10000) {                              // 10 másodpercenként nullázom az imp_10sec változót, kiszámolom a széllökést és tárolom a maximumát
    napi_atlag_seb=((float)(imp_atlag)*2.5)/szeles_ido;         //napi átlag a napi impulzusszámból és a szeles (amikor forog a kerék akkor növeljük másodpercenként) 
                                                                //másodpercek számából
    szellokes=((float)(imp_10sec)/10)*2.5;                      //10 másodperces széllökés értékének frissítése
    if (szellokes_max<szellokes) {szellokes_max=szellokes;}     //széllökés maximum frissítése
    imp_10sec=0;                                                //újra kezdjük a 10 másodperc alati impulzusok mérését
    ido_tmp_10=millis();                                        //elkezdődik a 10 másodperc mérése ezzel a kezdőértékkel
  }
  
  if (millis()>szelkerek_ido+1000) {                            //egy másodpercenként frissítem a pillanatnyi szélsebesség értékét,  
                                                                //ha éppen az időt állítjuk be, akkor nem  számoljuk az impulzusokat, mert ott delay() van!
    if (!all) {                                                 //nem áll a szélkerék, lehet sebességet számolni
      pill_szelseb=2.5*(1000/(float)ford_ido);                  //pillanatnyi szélsebesség kiszámítás egy körülfordulás idejéből. Ha a fordulási idő 1000, 
                                                                //akkor egy másodperc alatt éppen egyet fordul, és ha nő a sebesség, akkor ez növekszik. Pl ha kettőt fordul,
                                                                //akkor 1000/500=2-val szorozzuk az egy fordulatra megadott szélsebességet.
      szeles_ido++;                                             //növeljük a szeles idő idejét másodperc alapon mérő számlálót az átlag sebesség meghatározáshoz
    }
    else {szel_mentes_ido++;}                                   //növeljük a szélmentes idő értékét 1 másodperccel (áll a szélkerék)
    szelkerek_ido=millis();                                     //innen indul egy új egy másodperces időzítés
  }

   
  if (ejfel>=1440) {imp_atlag=0;szeles_ido=0;ejfel=0;}           //24 óra elteltével nullázzuk a napi impulzusgyüjtőt és a napi szeles idő változóját, és 
                                                                //újra indul az ejfel szamlaló, ami percenként növekszik. 24 óra 1440.

  if (millis()>percidozito+60000) {                             //egy percenként növeljük az ejfel változót
    ejfel++;                                                    
    percidozito=millis();
  }

  /*************************************************************************************************************************************
   * Az itt következő programrészek a nyomógombot figyelik. Megtörténik a prellmentesítés. Mivel a hosszú megnyomásnak                 *
   * szerepe van, a nyomógomb elengedés indítja az akciókat. Egy megnyomás bekapcsolja a háttérvilágítást (ez a nyomógomb lenyomással  *
   * törtéik nem az elengedéssel). Ha már világít a háttérvilágítás, akkor növeljük a kijelzett adat indexértékét. Ha hosszan          *
   * nyomvatartjuk az időkijelzés óra és perc felirattal jelzett állapotában, akkor az óra illetve a perc értékét növeli               *
   * ciklikusan, ha elérte a 23-at (óra) illetve az 59-et (perc), akkor 0-ról indul újra. Ha egy ilyen bállítás után                   *
   * elengedjük a gombot, akkor ezzel be is állítottuk az órát.                                                                        *
   *************************************************************************************************************************************/
  //megnyomta a nyomógombot, de még lehet, hogy prelles
  if (digitalRead(3)==LOW and nyomva==LOW) {    //megynomta a setup gombot
    nyomva_ido=millis();  //prellmentesítéshez ezzel indul az 50msec időzítése
    nyomva=HIGH;  //innen tudjuk, hogy már történt egy kontaktus, 50 msec múlva már biztosan prellmentes
    lcd.backlight();vilagitas_ido=millis();   //bekapcsoljuk a háttérvilágítást, és elindítjuk a kikapcsolási időzítést
                                          //lcd_vilagitas változót még nem billentjük be, az fogja jelezni később, hogy lehet léptetni 
                                          //a kijelzett adat indexét

    }    
  //ha 50msec mulva is nyomva tartja,akkor ez már nem prelles, biztosn nyomva van, lehet belépni a setup folyamatba
  if (digitalRead(3)==LOW and millis()>nyomva_ido+50 and nyomva==HIGH) {setup_mod=HIGH;}       //mar itt is lehetne növelni a kijelzett adat index értékét
                                                                                               //de az óra beállítás miatt az elengedéskor növelek (ha már 
                                                                                               //bilágít a háttérvilágitás, mert ha nem akkor csak azt bekapcsolom)
                                                                                               //ha 1 másodpercnél tovább nyomom, és nem az órabeállításban vagyok
                                                                                               //akkor nem fog történni semmi
  //elengedte a nyomógombot, de még lehet, hogy prelles
  if (digitalRead(3)==HIGH and elengedve==LOW and nyomva==HIGH) {elenged_ido=millis();elengedve=HIGH;}
  //már 50msec óta elenged, biztosan nem prelles, beállítási értéket váltunk, lehet várni az új megnyomásra
  if (digitalRead(3)==HIGH and elengedve==HIGH and millis()>elenged_ido+50)                    //amikor elengedjük a nyomógombot, akkor váltjuk a kijelzett értéket
                                                                                               //Ha azonban nem világított a háttérvilágítás, akkor ez a gombnyomás
                                                                                               //csak bekapcsolja azt, és nem léptet 
  {
    nyomva=LOW;
    elengedve=LOW;
    Serial.println(lcd_vilagitas);
    if (lcd_vilagitas==LOW) {lcd_vilagitas=HIGH;}  //ezzel elnyeljük az első nyomógomb lenyomást, ha nem világított a háttérvilágítás (csak bekapcsoljuk azt)
    else {                     //már világit a háttérvilágítás, lehet az adatindexet növelni
      adat_index++;
      if (adat_index>7) {adat_index=0;}            //a legutolsó adat után újra a legelső adatot fogjuk kiírni
      frissit=true;                                //azonnal frissíteni kell a képernyőt, mert gombnyomás történt
      vilagitas_ido=millis();                          //innen indul a 60 másodperc időzítés a háttérvilágítás kikapcsolására
    }
  } 

  if (millis()>vilagitas_ido+60000)   //ha 60 másodperce nem nyúlt a nyomógombhoz akkor a háttérvilágítást kikapcsoljuk 
  {
    lcd_vilagitas=LOW;
    lcd.noBacklight();
  }

  if (digitalRead(3)==LOW and setup_mod==HIGH and nyomva==HIGH and millis()>nyomva_ido+1000)   //egy másodpercig nyomvatartotta, változtatjuk az óra vagy a perc értékét
                                                                                               //elengedéskor az éjfél óta eltelt időt már be is állítottuk 
  {
    ora=ejfel/60;                               //ejfel változóból kiszáítjuk az óra értékét
    perc=ejfel-(ora*60);                        //ejfel változóból kiszámítjuk perc értékét
    if (adat_index==6) {                      //ha az éppen kijelzett adat az óra volt, akkor óra értékét fogjuk növelni
      do {
        ora++;if (ora>23) {ora=0;}
        lcd.setCursor(11,1); 
        lcd.print(ora);lcd.print("  ");       //kiírjuk az óra aktuális értékét
        ejfel=ora*60+perc;                    //minden növelési ciklusban kiszámítjuk ejfel értékét
        delay(700);
      } while (digitalRead(3)==LOW);          //addig fut a ciklus, amíg nyomjuk a gombot
    }
    if (adat_index==7) {
      do {
        perc++;if (perc>59) {perc=0;}
        lcd.setCursor(12,1); 
        lcd.print(perc);lcd.print("  ");
        ejfel=ora*60+perc;
        delay(700);
      } while (digitalRead(3)==LOW);
    }
    setup_mod=LOW;                             //kilépünk a setup módból, gombnyomás mentes álapot jut érvénre, frissül a képernyő másodpercenként az aktuálisn kijelzett adattal
    frissit=true;                              //azonnal frissíteni kell a képernyőt, mert változtattunk az idő értékén
    nyomva=LOW;                                //elengedtük a nyomógombot
    percidozito=millis();                      //innen indítjuk az egy perc időzítését az éjfel szamlaló növeléséhez
    vilagitas_ido=millis();                    //innen indul a 60 másodperc időzítés a háttérvilágítás kikapcsolására
  }

  /*******************************************************************************************************************************
   * Ebben a részben a kijelzőn megjelenő adatot frissítjük másodpercenként. Hogy mit lehet látni a kijelzőn azt az adat_index   *
   * változó dönti el, amit a nyomógomb lenyomásokkal tudunk változtatni, növelni 0 és 7 között. A 6. és 7. index érték          *
   * esetén az időt jelezzük ki, és ha ekkor megnyomjuk hosszan a nyomógombot, akkor a perc illetve az óra értéke változtatható  *
   * amit a nyomógomb elengedésekor azonnal frissítünk is.                                                                       *
   *******************************************************************************************************************************/
  if (millis()>kijelzo_valtas_ido+1000 or frissit) {  //két másodpercenként frissítjük a mért értékeket, ha éppen beállítjuk 
                                                                   //az éjfélig hátralévő időt, akkor nem
    frissit=false;  //ettől kezdve már csak másodpercenként frissítünk
    switch (adat_index) {
       case 0:         //pillanatnyi széllsebesség értékének kiírása
        lcd.setCursor(0,0);lcd.print("Pill. szelseb:  ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(pill_szelseb)+5,1);lcd.print(pill_szelseb,1);  //egy tizedesjegy hosszan kiírjuk a pillanatnyi szélsebességet
                                                                              //a kiírás kezdő pozicióját a szélsebesség nagyságrendje határozza meg,
                                                                              //hogy ne vándoroljon a kiírt szám, így a tizedespont egy helyben marad
        break;
       case 1:         //széllökés értékének kiírása
        lcd.setCursor(0,0);lcd.print("Szellokes:      ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(szellokes)+5,1);lcd.print(szellokes,1);
        break;
      case 2:         //széllökés maximum értékének kiírása
        lcd.setCursor(0,0);lcd.print("Szellokes max.: ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(szellokes_max)+5,1);lcd.print(szellokes_max,1);
        break;
      case 3:         //24 órás átlag sebesség (csak a szeles időszakot vesszük figyelmebe)
        lcd.setCursor(0,0);lcd.print("24h atlag seb.: ");
        lcd.setCursor(0,1);lcd.print("            km/h");
        lcd.setCursor(poz_szam(napi_atlag_seb)+5,1);lcd.print(napi_atlag_seb,1);
        break;
      case 4:         //szeles időszak idejének kiírása óra perc kijelzéssel (ennyi ideig forgott a szélkerék)
        ora=szeles_ido/3600;
        perc=(szeles_ido-ora*3600)/60;
        lcd.setCursor(0,0);lcd.print("Szeles idoszak: ");
        lcd.setCursor(0,1);lcd.print("                ");
        lcd.setCursor(7,1);lcd.print(ora);lcd.print("o ");lcd.print(perc);lcd.print("p   ");
        break;
      case 5:         //szelmentes időszak idejének kiírása óra perc kijelzéssel (ennyi ideig ált a szélkerék)
        ora=szel_mentes_ido/3600;
        perc=(szel_mentes_ido-ora*3600)/60;
        lcd.setCursor(0,0);lcd.print("Szelmentes ido- ");
        lcd.setCursor(0,1);lcd.print("szak:           ");
        lcd.setCursor(7,1);lcd.print(ora);lcd.print("o ");lcd.print(perc);lcd.print("p   ");
        break;
      case 6:         //idő kijelzése (ha hosszan nyomjuk a gombot, akkor beállíthatjuk az óra értékét)
        ora=ejfel/60;
        perc=ejfel-(ora*60);
        lcd.setCursor(0,0);lcd.print("Ido:            ");
        lcd.setCursor(6,0);
        if (ora<10) {lcd.print("0");}
        lcd.print(ora);lcd.print(":");
        if (perc<10) {lcd.print("0");}
        lcd.print(perc);lcd.print("  ");
        lcd.setCursor(0,1);lcd.print("Ora beall.:     ");
        break;
      case 7:         //idő kijelzése (ha hosszan nyomjuk a gombot, akkor beállíthatjuk a perc értékét)
        ora=ejfel/60;
        perc=ejfel-(ora*60);
        lcd.setCursor(0,0);lcd.print("Ido:            ");
        lcd.setCursor(6,0);
        if (ora<10) {lcd.print("0");}
        lcd.print(ora);lcd.print(":");
        if (perc<10) {lcd.print("0");}
        lcd.print(perc);lcd.print("  ");
        lcd.setCursor(0,1);lcd.print("Perc beall.:     ");
        break;
    }
    kijelzo_valtas_ido=millis();
  }
  
}

/******************************************************************************************
 * Ez a függvény a kijelzés kezdő poziciójához ad vissza egy eltolási értéket a kijelzett *
 * szám nagyságától függően                                                               *
 ******************************************************************************************/
byte poz_szam(byte adat)  //Az adat változóba beolvasott szám nagyságától függően 0,1,2-t ad vissza a kiírás könnyítéséhez
{
    if (adat<100) {                              //ha kisebb mint 10, akkor kettővel vagy eggyel kell eltolni a számot
      if (adat<10) {return 2;} else {return 1;}  //ha tiznél kisebb akkor eggyel kell eltolni
    } else {return 0;}                           //ha 100-nál nagyobb akkor nincs eltolás
}

Mennyire volt hasznos amit olvastál? Értékelés után szövegesen is leírhatod megjegyzéseidet és véleményedet!

Kattints egy csillagra az értékeléshez!

Szövegesen is leírhatod véleményedet! Ha kérdésed van, ne felejtsd el megadni az email címedet!