lauantai 14. toukokuuta 2016

Ja leikki jatkuu

Oikeastaan Arduino mikrokonttrolleri ei ole mikään tietokone, vaan yksi elektroniikan ”komponentti” muiden komponenttien joukossa. Toki ohjelmoinnilla on paljon helpompi saada aikaan erilaisia toimintoja kuin erilliskomponenteista rakentamalla. Tähän mennessä olen käyttänyt (tässä blogissa) samaa kontrolleria (paitsi kelloon jäi jatkuvaan käyttöön) eri sovelluksiin, mutta lopullinen tarkoitus on tuoda eri ideoita ja keinoja erilasten hyötysovellusten toteutukseen. Toki tämä leikkiminen ja luovuus ovat tärkeässä asemassa. Sen huomaa siitäkin, miten paljon erilaista anturia ja lisälaitettä netissä on tarjolla Arduino-maailmaan.
Mökillä on sähköt toteutettu aurinkopaneeleilla ja tuuligeneraattorilla. Sen vuoksi monet tähänastiset sovellukset liittyvät juuri tähän maailmaan. Kaikki laitteet toimivat 12V akkusähköllä. Toimivia laitteita ovat akkujen ylilatauksen valvonta, akkujen liian purkamisen esto, aurinkopaneelien kääntö, akkujen jännitteen näyttö jne. Näistä ei ole kuvia, mutta jäljempänä joitakin näihin liittyvää. Aina ei paista, ei edes päivisin. Jääkaapin syötössä on siksi valvontalaite. Jos akun varaus ei riitä, vaan yöllä jännite laskee, pudottaa valvontalaite jääkaapin pois. Akkua ei saa purkaa liikaa. Jääkaapin sisältö pysyy kyllä kylmänä aamuun saakka, kun ovea ei avata. Aamulla jälleen toivotaan aurinkoista päivää.

Akut eivät ole ikuisia. Nykyään ne ovat kiinnostuksen ja kehityksen kohteita, koska autoliikenteen toivotaan siirtyvän sähkökäyttöiseksi. Edelleen akkujen kapasiteetti pienenee jokaisesta latauskerrasta ja myös vuosien mittaan. Kuvassa oleva laite kytketään täyteen ladattuun akkuun, painetaan nappia, valo syttyy ja laite ryhtyy purkamaan akkua. Purkaus päättyy, kun akun jännite on laskenut 10V:iin. Purkauslaitteena on auton lamppu. Vaihdossa pitkien valojen puoli on jäänyt ehjäksi, joten se on saanut tässä jatkokäytön. Purkusvirta on noin 5A. Näyttönä on analogianäyttö, mikä pysähtyy johonkin lukemaan välille 0 .. 100Ah (ampeerituntia). Käytetty aika muutetaan analogialähdöllä jännitteeksi. Ei tällä ”mittarilla” aivan tarkkaa kapasiteettia saada mitattua, mutta luotettavan vastauksen siihen, pitäisikö vanha akku jo korvata uudella.

Mittausteni mukaan aurinkopaneelin tuotto pienenee puoleen noin 45 asteen kulmassa. Maa pyörii tämän kulman kolmessa tunnissa. Varsinaisista kääntäjistä minulla ei nyt ole kuvaa, mutta parista erityyppisestä pienoismalliprototyypistä on. Näiden tärkein tehtävä oli toiminta ohjelmakehitysksessä. Tuossa kuvassa oleva jäljittelee vanhanaikaista auton tunkkia. Sen toinen haara on kiinteä, ja kun ruuvi vetää haaraa avoimemmaksi, kääntyy pystyakseli. Tällä pääsee noi 90 asteen kääntymään. Jos kääntö käynnityy klo 09:00, seuraa paneeli aurinkoa 6 tuntia eli kello 15:00 saakka. Yli 50% tuotto saadaan siis kello kuudesta aamusta kello kuuteen illalla.

Toisessa käytössä olevassa tyypissä (tässä jälleen pienoismalli ohjelmakehitystä varten) moottori pyörittää pitkää ruuvia putken sisälä. Putkeen on uurrettu pitkittäinen hahlo, joka kiertää puoli kierrosta. Haitan siirtyessä pitkin ruuvia, samalla kiertyy putki, mihin paneeli on kiinnitetty. Tällä menetelmällä päästään 180 asteen eli 12 tunnin seurantaan. Siirto tapahtuu (kuten edellisessäkin mallissa) tunnin välein. Kääntö jään 7,5 astetta jälkeen ja siirtyy sitten 7,5 astetta edelle aurinkoa. Pilville ei sitten mahda mitään. Jos taivas on täysin umpipilvinen, pienenee paneelin tuotto helposti parin prosentin luokkaan. Käytössä on ollut myös hammasratasvaihteistolla toteutettu kääntäjä ja kehitteillä on malli, jossa veneen tuulilasinpyyhkijä naksauttaa aina ratasta eteenpäin. Tuollakin on mahdollista päästä noi kuuden tunnin seurantaan.



LEDilammpu meni taannoin rikki, niin pitihän se tutkia, mitä se oli ”syönyt”. Itse LEDipaneeli oli toimiva, ja toimi 12V:in jännitteellä, joten sain siitä idean tehdä valaisimen mökille. Siinä on kaksi toimintaa: Kytkimen toisessa asennossa syttyy valo ja toisessa asennossa laite toimii hämärkytkimenä. Siinä valovastus mittaa valoisuutta ja kytkee valon päälle, kun tulee tarpeeksi pimeää. Raja on säädettävissä potentiemetrillä. Kumpikin valo on säädettävissä (PWM) siten, että joka toinen painikkeen painaminen lisää valoa ja joka toinen himmentää. Tuo oli käytössä jo viime kesän lopulla, mutta vaati ohjelmistopäivitystä. Tärkein muutos oli kuitenkin valovastuksen liittäminen johdon päähän, joten se ei ole enää lähellä valokiilaa. Viime kesänä se pyrki toimimaan vilkkuvalona.



Tämä laite on oikeastaan jo täyttänyt päätehtävänsä. Toivottavasti sille löytyy vielä käyttöä ohjelmakehityksessä. Rinnan sisään / sarjassa ulos - IC-piiri 74HC165 lukee painikkeitten tilaa rinnakkaismuodossa ja siirtää datan sarjamuodossa Arduinolle. Sarjassa sisään / rinnan ulos – IC-piiri 74HC595 lukee sarjassa Arduinolta ja jakaa datan rinnan ulos. Tässä on indikaattorina 7-segmenttinäyttö. Molemmat piirit ovat kahdeksan(8) bittisiä, mutta näitä voidaan kytkeä peräkkäin. Näin voidaan helposti mikrokontrollerin IO-avaruutta laajentaa merkittävästi.


Arduinon ympärille on kehittynyt oikein maailman laajuinen tohina. Siitä elävin merkki on valtava netissä oleva ohjelmaesimerkkien paljous sekä monipuolinen lisälaitetarjonta. Tuossa kuvassa on vain muutama anturi. Tarjolla on runsas määrä moduleita Arduinoille. On ultraääntä (US), on infrapunaa (IR), on radiotaajuudelle (RF), on laseria, on lämpötilan ja kosteuden mittaukseen, painikkeita, joystick:iä, potikkaa jne. on innostavat mahdollisuudet mielikuvitukselle ja innovaatioille.


JA LEIKKI JATKUU!

keskiviikko 11. toukokuuta 2016

2-napainen sähkömoottori



Sähkömoottori tarjoaa uudenlaista liikettä. Aiemmin ”kaiuttimen” kalvo värähteli, mutta liike oli niin pieni, että sitä oli mahdoton nähdä. Sen ainoastaan kuuli ”musiikkina”. Tämä kokeilusarjaan kuuluva sähkömoottori on kooltaan suuri (teholtaan pieni). Moottorin rakenne on helppo nähdä. Akselissa on kaksi pyörivää, toisilleen vastakkaista napaa, jotka magnetoidaan sähkövirralla. Tämän osan nimi on roottori. Se pyörii kahden kiinteän kaaren välissä. Sen nimi on staattori. Sekin on magneettinen. Se magnetoidaan näiden staattoriosien välissä olevalla kestomagneetilla. Roottorin pyöriminen perustuu siihen, että erinimiset magneettinavat vetävät toisiaan puoleensa ja samannimiset hylkivät toisiaan. Kun rootorin navat pyöriessään vaihtavat puolta, on napojen magneettikentän suuntakin vaihdettava. Samalla akselillä roottorin kanssa pyörii kaksi puolipyöreää kupariliuskaa. Ne muodostavat virran kääntäjän eli kommutaattorin. Siihen nojaa kaksi kupariliuskaa, eli moottorin harjat. Niiden kautta roottorin käämit saavat magnetointivirtansa.Roottori toimii toisin sanoen sähkömagneettina. Jokaisen puolikierroksen jälkeen vaihtuu sähkövirran suunta roottorin käämeissä. Samalla vaihtuu roottorin magneettinapojen suunta.

Siinäpä olikin tämän moottorin hyvät puolet. Jos kokeilee kahdella magneetilla tuoden niitä lähemmäksi toisiaan, voi huomata että mitä lähempänä ne ovat, sitä voimakkaammin ne joko vetävät tai hylkivät toisiaan. Tässä moottorissa staattorin ja roottorin väli on varsin suuri. Magneettinen kenttä ei voi kasvaa kovin suureksi, joten vetovoimakin jää heikoksi. Moottori on hyvin heikkotehoinen. Hyvä että jaksaa itsekseen pyöriä.


Toinen ongelma on kaksinapaisuus. Jos navat ovat vaakasuorassa, irrottaa kommutaattorin liuskojen välissä olevat kohokkeet harjat irti kommutaattorista, joten virran kulku katkeaa. Jos näin ei olisi, syntyisi oikosulku ja sulake kärähtäisi. Tämä on tietysti sulakkeen tehtäväkin — suojella virtalähdettä. Tämä tarkoittaa sitä, että pyörijän ollessa vaakasuorassa, moottori ei lähde käyntiin ilman apua. Se näkyy selvästi myös oheisessa videossa. AntinArdubitit19.youtube.com (vahingossa väärällä nimellä, mutta kopiomalla tuo gogleen, tuntuu kuitenkin löytyvän. Kesto 22s).

Moottoria ohjataan releyksikön kautta. Näitä yksiköitä on saatavilla valmiina yhdelle tai useammalla releellä (4 Relay Module). Olen tässä käyttänyt nelireleistä, koska niitä sattuu laatikosta löytymään. Kaksi relettä jää siis vapaaksi. Rele vetää, kun sen käämiin johdetaan sopiva sähkövirta. Tämän moduulin releet syötetään 5V:in jännitteellä. Koska rele vaatii vetääkseen tehoa, on, johtuen tuosta melko pienestä jännitteestä, virran oltava melko suuri. Siksi en syötä relemoduulia Arduiinosta, vaan erillisestä virtalähteestä. Kun rele vetää, syntyy siihen magneettikenttä. Mutta kun ohjaus loppuu, se päästää. Sen käämissä on kuitenkin edelleen magneettikentä, jonka pitää purkautua. Nyt kuitenkin ohjauksen loputtua, piirin vastus kasvaa oleellisesti. Ohmin lain mukaan jännite on virran ja vastuksen tulo (U = I * R). Nyt virta ei kuitenkaan pääse mihinkään, koska syöttöpiiri katkaistiin (vastus lähes ääretön), pyrkii jännite kasvamaan hyvin suureksi. Syntyy häiriöpiikki, mikä aiheuttaa mikrokontrollerissa ongelmia jos tähän ei varauduta. Relelevyllä on releiden rinnalla diodit, jotka purkavat ja vaimentavat tämän poistuvan magneettikentän aiheuttaman jännite- ja virtapiikin. Toinen suojaustoimenpide on optoerottimien käyttö ohjauspuolella. Arduinon lähdöt eivät ohjaa suoraan releitä, vaan välissä on galvaaninen erotin. Toisin sanoen Arduinon ja releyksikön välillä ei ole sähköisesti johtavaa yhteyttä, vaan ohjaus muutetaan välillä valoksi. Huomattava on myös, että releet vetävät silloin, kun digitaalilähtö menee nollaan (0 = LOW) ja päästää kun lähtö on yksi (1 = HIGH). Muutoin ohjelma on varsin yksinkertainen. Ensin moottoria pyöritetään yhteen suuntaan, pieni tauko, sitten toiseen suuntaan, tauko ja hyppy alkuun. Kolmannessa kuvassa näkyy osien keskinäinen kytkentä ja lopuksi kytkennän kaavio.










/***************************************
 *  Ohjelma 19
 *  09.05.2016
 *  Sähkömoottorin ohjaus
 **************************************/

// MÄÄRITTELYT:
const int Con_MoEteen = 2;
const int Con_MoTaakse = 3;
const int Con_ViiKay = 2500;
const int Con_ViiSeis = 50;
int Int_ViiKay = Con_ViiKay;
int Int_ViiSeis = Con_ViiSeis;
int Seq_Ohjaus = 1;

// ASETUKSET:
void setup(){                 
 Serial.begin(9600);         
  pinMode(Con_MoEteen, OUTPUT);
  pinMode(Con_MoTaakse, OUTPUT);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){

switch (Seq_Ohjaus) {
  case 1:
   digitalWrite(Con_MoEteen, LOW);
    Int_ViiKay--;
    if (Int_ViiKay == 0){
      Int_ViiKay = Con_ViiKay;
      Seq_Ohjaus = 2;
    }
    break;
  case 2:
   digitalWrite(Con_MoEteen, HIGH);
    Int_ViiSeis--;
    if (Int_ViiSeis == 0){
      Int_ViiSeis = Con_ViiSeis;
      Seq_Ohjaus = 3;
    }
    break;
  case 3:
   digitalWrite(Con_MoTaakse, LOW);
    Int_ViiKay--;
    if (Int_ViiKay == 0){
      Int_ViiKay = Con_ViiKay;
      Seq_Ohjaus = 4;
    }
    break;
  case 4:
   digitalWrite(Con_MoTaakse, HIGH);
    Int_ViiSeis--;
    if (Int_ViiSeis == 0){
      Int_ViiSeis = Con_ViiSeis;
      Seq_Ohjaus = 1;
    }
    break;
}
  
delay(1);

} // Pääohjelma LOPPU

perjantai 6. toukokuuta 2016

Enemmän sähkötehoa

Kun ohjataan hehkulamppuja, releitä, moottoreita ja muita enemmän sähkötehoa kuluttavia laitteita, ei USB-liittimeltä tai Arduinon stabilisaattorilta saatava teho enää riitä. Yksittäisen lähtöpinnin maksimi kuorma saa olla 40mA ja useamman pinnin yhteiskuorma korkeintaan 400 mA. Näiden ylitys tuhoaa mikrokontrollerin. Näin tapahtuessa on suunnaton etu, että nämä digitaalilaitteet eivät maksa kovinkaan paljon.

Tämä jakso poikkeaa siinä, että tässä ei ole riviäkään ohjelmaa. Käsittelen tässä yhtä mahdollisuutta pienen yksikön rakentamiseksi, millä pääsee jo huomattavasti suuremman laitekokonaisuuden syöttöön. Laite pohjautuu kahteen integroituun stabilisaattoripiiriin 7809 (7808 myös mahdollinen) ja 7805. Kumpikin syöttää stabiloitua plus (+) jännitettä, edellinen 9V ja jälkimmäinen 5V. Arduinoa voi syöttää jännitevälillä 7 .. 12V. Jos ajattelee akkua, on sen jännite noin 12V, mutta ladattaessa jännite nousee oleellisesti. Kun akussa on täysi lataus, nousee jännite noin 14,2V:iin. Nyt kyseessä olevaa virtalähdettä voi syöttää akusta tai jostain, esim. käytöstä jääneestä, jonkin elektroniikkalaitteen laturista, minkä nimellisjännite on noin 12V ja nimellisvirta suurempi kuin 1A. Jos nimellisjännite on suurempi, noin 16 .. 17 V:n luokkaa, syntyy tässä stabilisaattoriyksikössä tarpeettoman suuri lämpöhäviö.

Seuraavassa jännitesovittimen kytkentäkaavio:
Tulopuolen ja lähtöpuolen suodattimet ovat elektrolyyttikondensaattoreita. Niiden osalta on huolehdittava, että napaisuus on oikein. C1 on 470uF (mikrofaradia) ja C2 sekä C3 100uF. Jännitekestoisuus C1 35V ja kahdella muulla 100V. Pääasia näillä arvoilla on ainoastaan se, että jännitekestoisuus on riittävän korkea. Tässä toisena valintaperusteena oli se, että mitä sattui laatikosta löytymään. Piiri on hyvä suojata vahinkojen varalta sulakkeella. Tuo 1A on ihan hyvä, mutta 2A ei myöskään ole liikaa noiden stabilisaattoreiden kannalta. Sen määrää etupäässä se, millainen virran tarve on ulkoiselle kuormalle (+12V OUT). Piirilevynä olen käyttänyt kehitystarpeisiin tarkoitettua levyä (Veroboard), missä on pitkittäisiä kupariliuskoja ja paljon reikiä komponenttien asennukseen. Toimiva kytkentä saadaan aikaan katkaisemalla kupariliuska tarpeellisista kohdista. Katkaisuun sopiva työkalu on 3mm poran terä.

Mekaaninen rakenne on varsin yksinkertainen. Taivutetun alumiinipellin päälle on kiinnitetty liitinrima ja siihen elektroniikkaosa. Integroidut stabilisaattoripiirit on kiinnitetty alumiinisen rungon takaosaan, mikä toimii samalla jäähdytyslevynä. Jäähdytystehoa on lisätty pellistä väännetyllä ”rimastolla”. Kuvassa satbilisaattoreita reunustava valkoinen tahna on hyvin lämpöä johtavaa ja tarkoitettu juuri tehokomponenttien tehokkaampaan jäähdytykseen. Samaa tahnaa olen sivellyt myös rungon ja ”jäähdytysriman” väliin. 





LCD-kello, versiot 2 .. 5

Motto toteutui taas kerran. Kyllä tuo Ohjelma 18 toimii, mutta ei tyydyttävästi. Myöhemmissä versioissa muutos on tullut lähinnä ajan käsittelyyn. Ensimmäisessä versiossa CoL_EroSekunti = 999; jätätti aivan liikaa. Arvo 985 jätätti hiukan, mutta liikaa ollakseen kello. Arvo 984 edisti liikaa. Oli siis tehtävä jotain.

Epäilin noita ajanvalintanauhassa (Seq_YlaRivi) olevia viiveitä delay(20). Syy niiden olemassa olemiseen johtui ylärivin tekstien välkkymisestä. Näyttö rauhoittui osin, mutta kaikki ei ollut kunnossa kuitenkaan. Välkkyminen johtui siitä, että jokaisella ohjelmakierroksella näytön ylärivi tyhjennettiin (lcd.print("                ");) ja heti perään teksti. Versiossa 2, jo käynnistettäessä (void setup(){ .. Fun_YlaRivi(1, Int_UT);) kutsutaan aliohjelmaa kerran ja kirjoitetaan UT-otsikko. Myöhemmin kirjoitetaan ainoastaan kerran ja vain silloin, kun otsikko muuttuu. Näyttö on rauhallinen laajasta katselukulmasta.

Kuten versioiden määrästä voi päätellä, niin ihan putkeen ei heti mennyt. Välillä jätätti parikin minuuttia vuorokaudessa ja välillä oli kuin katutrokarin kello: ” Osta!, tää on hyvä kello, tää ei kauaa tuntia huitase!” Versiossa 5 päädyin jakamaan ohjelman suorituksen nauhoille, jolloin mitään tarpeetonta tarkastelua (if) ei suoriteta. Tässä minuutit päivitetään vasta silloin, kun sekunnit tulevat täyteen. Samoin käsitellään tunnit minuuttien tullessa täyteen.

Tälle kellolle on tarkoitus järjestää pidempiaikainen käyttö. Siksi kiinnitin sen alumiiniseen kulmaan ja samalla kytkin jännitteen stabilisaattorin kautta. Kellon käyttö tulee olemaan osana radioamatööriasemaa. Siellä on 12V akkusyöttö. Siksi myös tuo kansainvälinen aika, mitä tuo harrastus käyttää. Akkusyöttö ei kuitenkaan suoraan käy Arduinolle, joten alla 9V stabilisaattorin kytkentä.
Tarjolla tähän sovellukseen on myös kirjasto-ohjelma Time.h, mutta sitä en tunne (ainakaan vielä). Se käsittää ajan tulostuksen vuositasolta sekuntiin saakka.
Jos tämän valitsemani ratkaisun tarkkuus ei riitä, on olemassa yksi hyvä vaihtoehto: voi mennä kirpparille ja ostaa paristokäyttöisen herätyskellon, missä on myös sekuntiviisari. Tämä on tärkeää, sillä silloin sekunnin pulssi on saatavissa valmiina. Tällä toteutuksella pääsee jo erittäin hyvään tarkkuuteen. Mutta tässä pieni ongelma on se, että kelloa syötetään tavallisesti 1,5V:in jännitteellä. Tällöin on kaksi vaihtoehtoa: joko vahvistaa kellon pulssi 5V:iin ja digitaalitulolle sopivaksi, tai lukea tätä pulssia analogiatulon kautta. 

Tässä viimeisessä ohjelmaversiossa (_v5) CoL_EroSekunti = arvolla 998 antoi jo melko pienen jätätyksen = 48s/vrk. On huomattavasti helpompi ohjelmallisesti käsitellä jättävää kuin edistävää ”kelloa”. Nyt vuorokauden vaihtuessa voi sekuntien lähtöarvoksi ladata 48, jolloin ensimmäinen minuutti on tynkä, mutta ei kai sillä yösydännä ole niin väliä. Jos laittaa ajan oikeaksi päivällä kello 12:00, on ajan näyttö hiukan edellä ennen puolta päivää ja jätättää iltapäivän edistyessä. Eikä tämä muutenkaan aivan täydellinen ole. Koska aika käsitellään UT:na, ollaan kesäaikana 3 tuntia edellä. Näyttö kuitenkin rajoitetaan 24:ään, jolloin näyttö jumittuu keskiyötä lähestyttäessä tuohon lukemaan. Talviaikaan tuntia myöhemmin. Aamuyöstä näyttö palautuu normaaliksi. Tokko tuollakaan suurta merkitystä, sillä toivottavasti silloin ollaan jo unten mailla. Se on korjattavissa haluttaessa ehdollisella vähennyslaskulla. Jos UT on kesäaikaan > 20, vähennetään 24 ja talviaikaan suurempi kuin 21, tehdään sama vähennys.

Ohjelma 18v5
/*****************************************
 * Ohjelma 18v5
 * 05.05.2016
 * LCD-näyttö kellonajoille:
 * Universal Time, talviaika ja kesäaika
 *****************************************/

#include <LiquidCrystal.h>
// Näytön pinnit
LiquidCrystal lcd(8, 9, 4, 5,6,7);

int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
 
// MÄÄRITTELYT:
// Kellon määrittley
unsigned long Ulo_MilliSek = 0;
unsigned long Ulo_UusiMilliSek = 0;
const long CoL_EroSekunti = 998;
int Int_Sekunti = 0;
int Int_Minuutti = 0;
int Int_Tunti = 0;
int Seq_Aika = 0;
boolean Bol_Tulosta = false;

int Seq_YlaRivi = 1;
int Int_UT = 0;
int Int_Talvi = 1;
int Int_Kesa = 2;
//int Int_Otsikko = 1;
int Seq_TuntiAsetus = 1;
boolean Kep_TuntiAs = false;
int Seq_MinAsetus = 1;
boolean Kep_MinAs = false;
int Seq_AjanEtAsetus = 1;
int Seq_AjanTaAsetus = 1;

// ASETUKSET:
void setup(){                
 Serial.begin(9600);         
 lcd.begin(16,2);
 Fun_YlaRivi(1, Int_UT);
}// Asetuksen loppu

// PÄÄLOOPPI                 
void loop(){
// Sisäisen kellon käyttö
Ulo_MilliSek = millis();
  if(Ulo_MilliSek - Ulo_UusiMilliSek > CoL_EroSekunti){
    Ulo_UusiMilliSek = Ulo_MilliSek;
    Seq_Aika = 1;
    if(Bol_Tulosta == true){Fun_Tulostus();}
  }

//Ajan hallintasekvenssi
switch (Seq_Aika){
  case 1:
    Int_Sekunti++;
    if(Int_Sekunti > 59){  
      Int_Minuutti++;     
      Seq_Aika = 2;
    }else{
      Seq_Aika = 0;
    }
    break;
  case 2:
    Int_Sekunti = 0;
    if(Int_Minuutti > 59){  
      Int_Tunti++;
      Int_Minuutti = 0;
      Seq_Aika = 3;
    }else{
      Seq_Aika = 0;
    }
    break;
  case 3:
    if(Int_Tunti > 23){  
      Int_Tunti = 0;
      Seq_Aika = 0;
      Int_Sekunti = 48;
    }
    break;
}

// Näytön valintasekvenssi
lcd_key = read_LCD_buttons(); // Näytön painikkeet
switch (Seq_YlaRivi) {
  case 1:
    if(lcd_key == 4){
      Fun_YlaRivi(3, Int_Talvi);
      Int_Tunti = Int_Tunti +2;
      Seq_YlaRivi = 2;}
    break;
  case 2:
    if(lcd_key == 5){Seq_YlaRivi = 3;}
    break;
  case 3:
    if(lcd_key == 4){
      Fun_YlaRivi(3, Int_Kesa);
      Int_Tunti = Int_Tunti +1;
      Seq_YlaRivi = 4;}
    break;
  case 4:
    if(lcd_key == 5){Seq_YlaRivi = 5;}
    break;
  case 5:
    if(lcd_key == 4){
      Fun_YlaRivi(1, Int_UT);
      Int_Tunti = Int_Tunti -3;
      Seq_YlaRivi = 6;}
    break;
  case 6:
    if(lcd_key == 5){Seq_YlaRivi = 1;}
    break;
   }// Näytön valintojen loppu

lcd.setCursor(4, 1);
 if(Int_Tunti < 10){ 
  lcd.print("0");
  lcd.print(Int_Tunti);
 }else{lcd.print(Int_Tunti);}
  lcd.print(":");
 if(Int_Minuutti < 10){ 
  lcd.print("0");
  lcd.print(Int_Minuutti);
 }else{lcd.print(Int_Minuutti);}
lcd.print(":");
 if(Int_Sekunti < 10){ 
  lcd.print("0");
  lcd.print(Int_Sekunti);
 }else{lcd.print(Int_Sekunti);}

// Tunnin asetus
switch (Seq_TuntiAsetus) {
  case 1:
    if(lcd_key == 3){
      Kep_TuntiAs = true;
      lcd.setCursor(0, 1);
      lcd.print("t");
      Seq_MinAsetus = 1; Kep_MinAs = false;
      Seq_TuntiAsetus = 2;}
    break;
  case 2:
    if(lcd_key == 5){Seq_TuntiAsetus = 3;}
    break;
  case 3:
    if(lcd_key == 3){
      Kep_TuntiAs = false;
      lcd.setCursor(0, 1);
      lcd.print(" ");     
      Seq_TuntiAsetus = 4;}
    break;
  case 4:
    if(lcd_key == 5){Seq_TuntiAsetus = 1;}
    break;
} // Tuntiasetus loppu

// Minuutin asetus
switch (Seq_MinAsetus) {
  case 1:
    if(lcd_key == 0){
      Kep_MinAs = true;
      lcd.setCursor(0, 1);
      lcd.print("m");
      Seq_TuntiAsetus = 1; Kep_TuntiAs = false;
      Seq_MinAsetus = 2;}
    break;
  case 2:
    if(lcd_key == 5){Seq_MinAsetus = 3;}
    break;
  case 3:
    if(lcd_key == 0){
      Kep_MinAs = false;
      lcd.setCursor(0, 1);
      lcd.print(" ");     
      Seq_MinAsetus = 4;}
    break;
  case 4:
    if(lcd_key == 5){Seq_MinAsetus = 1;}
    break;
} // Minuuttiasetus loppu

// Ajan asetus eteenpäin
switch (Seq_AjanEtAsetus) {
  case 1:
    if(lcd_key == 1){
      if(Kep_TuntiAs == true){Int_Tunti++;}
      if(Kep_MinAs == true){Int_Minuutti++;} 
      if(Kep_TuntiAs == false && Kep_MinAs == false){
       Int_Sekunti++;  
      }
      Seq_AjanEtAsetus = 2;}
    break;
  case 2:
    if(lcd_key == 5){Seq_AjanEtAsetus = 1;}
    break;
} // Ajan eteenpäin asetuksen loppu

// Ajan asetus taaksepäin
switch (Seq_AjanTaAsetus) {
  case 1:
    if(lcd_key == 2){
      if(Kep_TuntiAs == true){Int_Tunti--;}
      if(Kep_MinAs == true){Int_Minuutti--;} 
      if(Kep_TuntiAs == false&& Kep_MinAs == false){
       Int_Sekunti--;  
      }
      Seq_AjanTaAsetus = 2;}
    break;
  case 2:
    if(lcd_key == 5){Seq_AjanTaAsetus = 1;}
    break;
} // Ajan taaksepäin asetuksen loppu

Int_Sekunti = constrain(Int_Sekunti, 0, 60);
Int_Minuutti = constrain(Int_Minuutti, 0, 60);
Int_Tunti = constrain(Int_Tunti, 0, 24);
//delay(1);
} // Pääohjelma LOPPU

// FUNKTIOT
void Fun_Tulostus(){
//Serial.print("Teksti :");  Serial.println(Muuttuja);

}
// Funktio Lue painikkeet:
int read_LCD_buttons(){
  adc_key_in = analogRead(0);
  if(adc_key_in > 1000)   return btnNONE;
  if(adc_key_in < 50)    return btnRIGHT;
  if(adc_key_in < 195)   return btnUP;
  if(adc_key_in < 380)   return btnDOWN;
  if(adc_key_in < 555)   return btnLEFT;
  if(adc_key_in < 790)   return btnSELECT;
  return btnNONE;
}
// Funktio päivitä yläotsikko
void Fun_YlaRivi(int Paikka,int Otsikko){
  char* Otsake[] = {"UNIVERSAL TIME","TALVIAIKA","KESA-AIKA"};
    lcd.setCursor(0, 0);
    lcd.print("                ");
    lcd.setCursor(Paikka, 0);
     lcd.print(Otsake[Otsikko]);

} // Yärivi loppu