sunnuntai 11. joulukuuta 2016

Joystick KY-023 ja KY-011

Tässä ohjelmajaksossa käsittelen joystick:in (KY-023) rajapintaa. Laite käsittää kaksi potentiometriä ( kumpikin arvoltaan noin 3,4 kilo-ohmia), jotka sijaitsevat mekaanisesti toisiinsa nähden ristikkäin. Voi siis ajatella, että toinen säätää pystysuuntaa ja toinen vaakasuuntaa. Näitä liikutellaan nupilla vapaasti näiden kahden suunnan välillä. Lisäksi yksikössä on kytkin, mikä toimii painamalla painiketta. Yksikkö on jousitettu siten, että kytkin on avoinna ja painike (melkein) keskiasennossa.

Potentiometrit on kytketty +5V:in ja maan (GND)väliin ja kytkimen painaminen oikosulkee lähtöpinnin maihin. Potentiometrin liuut kytketään analogiatuloihin ja kytkin digitaalituloon D2. Indikaattorina on puna/vihreä-LED (KY-011), joiden kirkkautta säädetään nupin asennolla. Painamalla kytkintä LEDit sammutetaan. Kahdella erillisellä LEDillä nupin asennon vaikutus olisi varmaan ollut selkeämpi. Värien kirkkausvaihtelut olisi olleet helpompi erottaa. (Ainakin tällaiselle puna- vihreä- värisokealle.)

OHJELMASTA
Ohjelma ei sisällä mitään kovin erikoista, mutta jotakin uutta. Painike on kytketty sisäisesti toisesta päästä maihin ja oikosulkee täten signaalitien. Tässä voi käyttää erillistä ylösvetovastusta, mutta voi asetuksissa konfiguroida käyttämään Arduinon sisäistä ylösvetoa (pinMode(Con_Kytkin, INPUT_PULLUP); Huomioitava on myös, että painettassa D2:n tulojännite muuttuu 5 → 0V eli ykkösestä nollaan, true → false. Siksi tulon tilan luku on käänteinen (Bol_Kytkin = !digitalRead(Con_Kytkin);) Siksi siinä on tuo huutomerkki (!).
Toinen huomioitava seikka on se, että analogiatuloja (potikat) ja analogialähtöjä (LEDit) ei tarvitse, eikä pidä määritellä asetuksissa. (Tosin analogiatulot voidaan määritellä myös digitaalisiksi. Toinen huomioitava seikka on, että kaikki digitaali-lähdöt eivät voi toimia analogialähtöinä.) Asetuksissa on myös myös pieni stabi-lointiviive ja siinä luetaan kertaluonteisesti joystick:in lepoitilan antamat jänniteen. Tässä tapauksessa ne olivat 500 (pysty) ja 505 (vaaka).

Pääohjelman aluksi luetaan painikkeen tila. Jos se on painettu, kirjoitetaan LEDien ohjausarvoiksi nollat (0) ja hypätään varsinaisen suoritusosan yli lähtöjen päivitykseen (analogWrite(LED, Arvo)); Arduinon C-ohjelmatyökalu sisältää goto label; - käskyn (nimi, tässä tapauksessa ohitus:), mutta sen käyttö EI OLE SUOSITELTAVAA!! Olen tässä yksinkertaisessa tapauksessa tuonut sen esimerkkinä esille, mutta ohjelman mutkistuessa se aiheuttaa todennäköisesti sekaannusta ja vaikeuksia. Suositeltavampaa on käyttää if(ehdot){toiminta; [}else if{ehdot ja toiminta; }else{toiminta;}] } tai varsin selkeätä rakennetta: switch (askel).. case(askel no.) .. break; Tällä saadaan selkeästi ohjelman suoritus rajoittumaan vain niihin tehtäviin, mitkä kyseisessä askeleessa pitää tehdä. Tämä tekee ohjelmasta suoritusnauharakenteisen.
     Suoritettavassa pääohjelmaosuudessa joystick:in ohjaamat jännitearvot muutetaan LEDien kirkkausarvoiksi. Koska lepotila ei ole muunnosalueen puolessa välissä (1024 / 2 = 512), pitää lepotilojen yläpuoliset ja alapuoliset arvot muuttaa erikseen analogisiksi lähtöarvoiksi (8-bittinen muunnos 0 .. 255). Yläpuoliset arvot välille 127 .. 255 ja alapuoliset välille 0 .. 126. Tähän käytetään käskyä lähtö = map(muuttuja, alku, loppu, alku, loppu).
     Lisäksi ohjelmassa on vielä vähennyslasku: Int_PystyOhjaus = 255 – Int_PystyOhjaus; Halusin, että vihreä kirkastuu ylöspäin ja punainen oikealle (kun stickin liittimet ovat itsestä pois päin). Nämä kaksi lausetta on tietysti tarpeettomia, jos joystick käännetään toisin päin.

OHJELMA 28
/***************************************
* Ohjelma 28
* 09.12.2016
* Joys stickin havainnointi
**************************************/

// MÄÄRITTELYT:
// IO- ja muistimääritykset
const int Con_Kytkin = 2;
boolean Bol_Kytkin = false;
int Int_KytkinViive = 0;
const int Ana_Vaaka = 0;
int Int_VaakaRaaka = 0;
int Int_VaakaPohja = 0;
int Int_VaakaOhjaus = 0;
const int Ana_Pysty = 1;
int Int_PystyRaaka = 0;
int Int_PystyPohja = 0;
int Int_PystyOhjaus = 0;
const int Con_LED_Pun = 3;
const intt Con_LED_Vih = 5;

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_Kytkin, INPUT_PULLUP); // Sisäinen ylösveto
delay(20);
// Luetaan joystickin pohjalukemat vaaka ja pysty
Int_VaakaPohja = analogRead(Ana_Vaaka);
Int_PystyPohja = analogRead(Ana_Pysty);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){

// Kytkimen luku
Bol_Kytkin = !digitalRead(Con_Kytkin);
// Painettaess sammutetaan LEDit
if(Bol_Kytkin == true){
Int_VaakaOhjaus = 0;
Int_PystyOhjaus = 0;
goto ohitus; } // Painettaessa hypätään mittausten yli

// Analogiamittaukset ja muunnokset
Int_VaakaRaaka = analogRead(Ana_Vaaka);
Int_PystyRaaka = analogRead(Ana_Pysty);
if(Int_VaakaRaaka >= Int_VaakaPohja){
Int_VaakaOhjaus = map(Int_VaakaRaaka,Int_VaakaPohja, 1023, 127, 255);
}else{
Int_VaakaOhjaus = map(Int_VaakaRaaka,0, Int_VaakaPohja, 0, 126);
}
Int_VaakaOhjaus = 255 - Int_VaakaOhjaus;
if(Int_PystyRaaka >= Int_PystyPohja){
Int_PystyOhjaus = map(Int_PystyRaaka,Int_PystyPohja, 1023, 127, 255);
}else{
Int_PystyOhjaus = map(Int_PystyRaaka,0, Int_PystyPohja, 0, 126);
}
Int_PystyOhjaus = 255 - Int_PystyOhjaus;
 ohitus:
analogWrite(Con_LED_Pun, Int_VaakaOhjaus);
analogWrite(Con_LED_Vih, Int_PystyOhjaus);
delay(1);
} // Pääohjelma LOPPU

keskiviikko 7. joulukuuta 2016

Pitomuisti KY-011, KY-017 ja KY-002

Elohopeakytkin KY-017
Koska tuo heiluri on vielä kiinnitettynä tuohon pöydän reunaan, on hyvä laatia ohjelman pätkä, mikä eliminoi elohopeakytkimen pisaran pomppimisen. On neljä tapausta: 1. elohopeakytkimen tila otetaan muistiin heti ensimmäisestä kosketuksesta ja muisti puretaan viiveen jälkeen, 2. muisti asetetaan vasta viiveen jälkeen, mutta palautetaan välittömästi pisaran irrottua, 3. sekä muistin asetus että palautus viiveen jälkeen, 4. tärinäanturin signaali otetaan heti muistiin ja asetetaan pitempi viive.
Käytän tässä elohopeakytkintä KY-017 ja tärinäanturia KY-002 muistin tilan ilmaisuun kaksiväristä LEDiä KY-011. Kun muisti on ykkönen (1), palaa punainen ja kun nolla (0) niin vihreä. Pitomuistin tunnuksena käytän ilmaisua Kep_ . Se tulee sanasta Keep = pitää, säilyttää, varastoida, pysyä.
Tärinäanturi KY-002
     Tärinäanturi (KY-002) poikkeaa toiminnaltaan oleellisesti elohopeakytkimestä sekä myös useimmista muista kytkimistä. Siinä on kaksi sisäkkäistä vieteriä, joista sisempi heilahtaa herkästi kiinni ulompaan. Anturilla on ainoastaan yksi stabiili asento, eli nolla (0), siis kytkin on johtamaton. Siksi tärähdys pitää ottaa muistiin, mikä puretaan vasta viiveen jälkeen. Ohjelmassa d, jokainen tärähdys myös nollaa viiveen, joten viive alkaa aina alusta. Tärähdysten lukumäärää voisi myös tilastoida ja tallettaa. Tarpeet riippuvat tietysti sovelluksesta.

Tärinän vaikutuksesta kytkinosa vain hipaisee toista kohtiota ja tulee hetkellisesti johtavaksi. Nykyään saa näköjään kännykkään apsin, mikä voi varoittaa maanjäristyksestä. Niin herkkä tämä tärinäanturi tuskin on ainakaan täällä meillä, mutta reagoi jo 1cm pudotuksesta. Myös tiukka isku pöytään sai sen toimimaan.
Jos ilkeä naapuri (sellaisia ei tietenkään todellisuudessa ole!) jyskyttää oveen, niin tuonhan voi järjestää ottamaan kuva. Samoin murtautujien varalle. Keksittävissä on tietysti monenlaista käyttöä.
Yllä olevasta kaaviosta näkyy, että antureiden kytkentä poikkeaa toisitaan. Samoin poikkeaa toiminnan suunta. Kun elohopeakytkin (KY-017) on aktiivinen, antaa se nollajänniteen ja kytkimen ollessa auki noin 3,6V (eikä 5V). Kun katsoo kytkentää, niin huomaa, että +5V:in jännite kulkee LEDin kautta. Tuo jännitepudotus johtuu LEDin myötäsuuntaisesta jännitehäviöstä. Tuokin jännite (3,6V) on riittävän korkea sille, että Arduinon digitaalitulo tulkitsee sen ykköseksi (1 = true).
Tärinäanturin merkinnät ovat hiukan ristiriitaiset ( - merkittyyn napaan kytketään +5V). Anturin sisällä on valmiina 10kohm;in vastus digitaalitulon maadoitusta varten. Tämän anturin toiminta on positiivinen, eli ollessaan aktiivinen, se antaa digitaalituloon 5V:in jännitteen.
LEDien etuvastukset (331ohm) on integroitu kuvassa ruskeana näkyvään piiriin. Alla on määrittelyosa vain kerran ja varsinaiset toimintaosat (loopit) erikseen.

 
OHJELMA 27a
/***************************************
* Ohjelma 27 (a, b, c ja d)
* 06.12.2016
* Värähtelevän kytkimen pitomuisti
**************************************/

// MÄÄRITTELYT:
// Viivelaskuri
const int Con_Kierrokset = 100;
int Int_Kierrokset = 0;

// Lähdöt, tulo ja muuttujat
const int Con_LED_Pun = 3;
const int Con_LED_Vih = 4;
const int Con_Anturi = 2;
boolean Bol_Anturi = false;
boolean Kep_PitoMuisti = false;
// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_Anturi, INPUT);
pinMode(Con_LED_Pun, OUTPUT);
pinMode(Con_LED_Vih, OUTPUT);
}// Asetuksen loppu

//OHJELMA 27a PÄÄLOOPPI
void loop(){
Bol_Anturi = !digitalRead(Con_Anturi);

// Viive asetuksessa
if(Bol_Anturi == true && Kep_PitoMuisti == false){
Int_Kierrokset++;
}else{
Int_Kierrokset = 0;
} // Asetuksen viive loppu

if(Int_Kierrokset > Con_Kierrokset){
Int_Kierrokset = 0;
Kep_PitoMuisti = true ;}

if(Bol_Anturi == false){
Kep_PitoMuisti = false;}

digitalWrite(Con_LED_Vih, !Kep_PitoMuisti);
digitalWrite(Con_LED_Pun, Kep_PitoMuisti);

delay(1);
} // Pääohjelma LOPPU

OHJELMA 27b
//OHJELMA 27b PÄÄLOOPPI
void loop(){
Bol_Anturi = digitalRead(Con_Anturi);// HUOM! ei käänteinen

// Viive palautuksessa
if(Bol_Anturi == true && Kep_PitoMuisti == false){
Int_Kierrokset++;
}else{
Int_Kierrokset = 0;
} // Asetuksen viive loppu

if(Int_Kierrokset > Con_Kierrokset){
Int_Kierrokset = 0;
Kep_PitoMuisti = true ;}

if(Bol_Anturi == false){
Kep_PitoMuisti = false;}

// LEDejä ohjataan ristiin
digitalWrite(Con_LED_Vih, Kep_PitoMuisti);
digitalWrite(Con_LED_Pun, !Kep_PitoMuisti);

delay(1);
} // Pääohjelma LOPPU

OHJELMA 27c
//OHJELMA 27c PÄÄLOOPPI
void loop(){
Bol_Anturi = !digitalRead(Con_Anturi);

// Viive asetuksessa
if(Bol_Anturi == true && Kep_PitoMuisti == false){
Int_Kierrokset++;
if(Int_Kierrokset > Con_Kierrokset){
Int_Kierrokset = 0;
Kep_PitoMuisti = true ;}
} // Asetuksen viive loppu

// Viive palautuksessa
if(Bol_Anturi == false && Kep_PitoMuisti == true ){
Int_Kierrokset++;
if(Int_Kierrokset > Con_Kierrokset){
Int_Kierrokset = 0;
Kep_PitoMuisti = false;}
} // Palautuksen viive loppu

digitalWrite(Con_LED_Vih, !Kep_PitoMuisti);
digitalWrite(Con_LED_Pun, Kep_PitoMuisti);

delay(1);
} // Pääohjelma LOPPU

OHJELMA 27d
const int Con_Kierrokset = 2000;

//OHJELMA 27d PÄÄLOOPPI
void loop(){
Bol_Anturi = digitalRead(Con_Anturi);

// Pitomuistin asetus
if(Bol_Anturi == true && Kep_PitoMuisti == false){
Kep_PitoMuisti = true ;
Int_Kierrokset = 0;
} // Asetuksen loppu

// Pitomuistin palautus
Int_Kierrokset ++;
if(Int_Kierrokset > Con_Kierrokset){
Int_Kierrokset = 0;
Kep_PitoMuisti = false;}

// LEDien ohjaus
digitalWrite(Con_LED_Vih, !Kep_PitoMuisti);
digitalWrite(Con_LED_Pun, Kep_PitoMuisti);

delay(1);
} // Pääohjelma LOPPU


sunnuntai 4. joulukuuta 2016

Maaginen valokuppi KY-027 ja KY-004

Nämä ”maagiset valokupit” koostuvat elohopekytkimestä ja punaisesta LEDistä. Ajatuksena on (siis sarja 37 tuottajan) vuorotellen kirkastaa ja himmentää näitä kahta LEDiä. Minun on vaikeata nähdä siinä mitään maagista. Ajattelinkin ensin hyljätä näiden yksiköiden käytön. Sitten keksin, että jos kiinnitän nämä heiluriin, niin silloin valot voisivat keikkua puolelta toiselle ja kirkastua kohti ääriasentoa. Kuulostaa tosi yksinkertaiselta. Onneksi en hylännyt, sillä edessä oli vaikeuksia, eli nykykielellä: projekti oli varsin haastava.

Etualalla käynnistyspainike
Tämä olisikin ohjelmallisen sovelluksen paikka, eikä niinkään näiden komponenttien esittely. Ohjelman käynnityessä pitää mitata heilahdusajan puolikas (aika lepotilasta ääriasentoon ja takaisin), puolittaa se ja muuntaa analogilähtöön (PWM = pulssin leveysmodulaatio) LEDien kirkkausignaaliksi. Ihan hyvää ohjelmointihaastetta.

Tätä voisi kehitellä eteenpäinkin: voisi tilastoida heilunnan vakautta lämpötilan ja kosteuden suhteen. Siitä voisi tehdä kellon sijoittamalla heiluriin magneetin, mikä saisi Arduinon ohjaaman sähkömagneetin antamia potkuja (vetää puoleensa erinapaiset ja työntävät samannapaiset) kompensoimaan kitkaa, johtojen jäykkyyttä ja imanvastusta. Ja mitä kaikkea muutakin? Tämä heiluri jaksoi heilua itskseen noin 8 minuuttia.

Elementtien kytkennät
Kun mittasin näitä komponetteja (KY-027) huomasin taas epämääräisyyksiä. Juotin kaikki pisteet uudestaan ja tein testiohjelman (Ohjelma26a), jolla oli helppo testata yksikkön toiminta. Elohopeakytkin ohjaa LEDin päälle ja pois. Huomaa, että kytkimen signaali on käänteinen. Siksi ohjelmassa on huutomerkki (!) digitaaliluennan edessä (digitalWrite(Con_LED, !digitalRead(Con_Kytkin));. Tällöin kytkimen ollessa kiinni, LEDi palaa ja kytkimen ollessa auki se sammuu. Elohopeakytkimessä ei tapahdu tyypillistä millisekunnin luokkaa olevaa kytkinvärähtelyä, joten mitään varmistuslooppia ei sitä varten tarvita. Elohopeapisara (Hg) on kuitenkin hyvin elastinen ja siinä on vahva pintajännitys. Tämä merkitsee sitä, että vaikka siinä ei ole lyhytaikaista värähtelyä, niin siinä on aivan silmin nähden olevaa pomppimista. Siksi ohjelmassa pitää varmista, että ohjelma reagoi juuri oikeaan aikaan tulevaan kosketukseen tai katkoon, eikä niihin ”pomppimisen” aiheuttamiin häiriöihin.

Tällä kerralla ohjelma jakaantuu kolmeksi eri ohjelmaksi: 26a:lla testasin ainostaan elohopeapisaran ja LEDin toiminnan. Ohjelmalla 26b etsin tasapainoa elohopeakytkimien välille ja samalla mitaten heilahdusaikaa (noin 1700ms. Ohjelma mittaa puolikkaita erikseen.). Ohjelma 26c on se varsinainen tavoite, missä LEDien kirkkaus kasvaa heilurin ääriasentoihin päin ja himmenee heilurin palatessa keskiasentoon. Video havainnoi tätä paremmin (antinarduvideo26. youtube.com). Aiemmin mainitsin haastavuudesta. Lyhyitä ohjelmapätkiä syntyi; myös versiot: d, e ja f, joilla hain sopivaa tapaa saada kirkastus ja himmennys synkronoitua ajallisesti heilahdusliikkeeseen. Heilurin asennosta saadaan signaali ainoastaan heilurin pystyasennosta, kun elohopeakytkimet vaihtavat tilaansa. Tämänkin hetken luotettavuutta häiritsi piraran pomppiminen.

Analogialähtö toimii niin, että lähtösignaali vaihtelee 0:n ja 5V:n välillä siten, että päällä- ja poisolon suhde muuttuu (PWM = Pulse-Width Modulation = pulssin leveysmodulaatio). Lähdöt, jotka voivat toimia analogialähtöinä, on Arduinossa merkitty “laineella” (~).
LEDien kirkkausohjaus on toteutettu sekvenssillä Vasen kirkastuu – vasen himmenee – oikea kirkastuu – oikea himmenee jne. Sekvenssi käynnistyy painamalla painiketta, mikä sijoittaa sekvenssimuuttujaan (Seq_MittSek) arvon yksi (1). Tähän ei enää palata, vaan viimeisestä askeleesta hypätään askeleeseen 3. Painamisen jälkeen puolikas heilahdusaika voidaan tulostaa ruudulle. Tämä suoritus on askeleessa 2. Tulostus tapahtuu siis vain kerran käynnistyspainikkeen painamisen jälkeen.
Analogialähtöä ohjataan kokonaisluvulla välillä 0 .. 255 (8-bittinen muunnos). Suora ohjaus kokonaisluvulla osoittautui hankalaksi, joten päädyin muodostamaan ohjausarvon ensin liukuluvulla (float) ja sen jälkeen sijoittamaan sen kokonaislukuun lähtöjen ohjausta varten. Ennen kuin päädyin tähän ratkaisuun, kuljeskelin monenlaisia turhauttavia ja epätyydyttäviä sivupolkuja. LEDien ja heilurin synkronointi onnistui aluksi laskemalla karkeasti heilahdusajasta, kokeilemalla ja sitkeästi hakemalla sopivaa arvoa.


OHJELMA 26a
/***************************************
* Ohjelma26a
* 25.11.2016
* Modulin (KY-027) toiminnan testaus.
* Kun kytkin on kiinni, LED palaa.
**************************************/

// MÄÄRITTELYT:
const int Con_LED = 2;
const int Con_Kytkin = 3;

// ASETUKSET:
void setup(){
pinMode(Con_Kytkin, INPUT);
pinMode(Con_LED, OUTPUT);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){

digitalWrite(Con_LED, !digitalRead(Con_Kytkin));

delay(1);
} // Pääohjelma LOPPU


OHJELMA 26b
/***************************************
* Ohjelma26b
* 29.11.2016
* Modulin (KY-027) toiminnan testaus.
* Painike käynnistää mittaussekvenssin
* b-versiossa tasapainotetaan puoliskot
* säätämällä elohopeakytkimien asennot
* ja mittaamalla heilahdusajat
**************************************/

// MÄÄRITTELYT:
// I/O-määrittelyt
const int Con_LED_Vas = 5;
const int Con_Hg_Vas = 2;
boolean Bol_Hg_Vas = false;
const int Con_LED_Oik = 6;
const int Con_Hg_Oik = 3;
boolean Bol_Hg_Oik = false;
const int Con_StartPain = 4;
boolean Bol_StartPain = false;
const int Con_LED_13 = 13;

// Ajan mittauksen määrittely
unsigned long Ulo_MilliSek = 0;
unsigned long Ulo_AlkuVasen = 0;
unsigned long Ulo_AikaVasen = 0;
unsigned long Ulo_AlkuOikea = 0;
unsigned long Ulo_AikaOikea = 0;
int Seq_MittSek = 0; // Mitataan heilahdusajat

// Tulostuksen tahdistus
const int Con_PrintViive = 1000;
int Int_PrintViive = Con_PrintViive;

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_Hg_Vas, INPUT);
pinMode(Con_LED_Vas, OUTPUT);
pinMode(Con_Hg_Oik, INPUT);
pinMode(Con_LED_Oik, OUTPUT);
pinMode(Con_StartPain, INPUT);
pinMode(Con_LED_13, OUTPUT);
}// Asetuksen loppu

// FUNKTIOT
void Fun_Tulostus(){
// Serial.print("Painike :"); Serial.println(Bol_StartPain);
// Serial.print("LEDi :"); Serial.println(Con_LED_13);
Serial.print("Vasen aika :"); Serial.println(Ulo_AikaVasen);
Serial.print("Oikean aika :"); Serial.println(Ulo_AikaOikea);
} // Tulostus loppu

// PÄÄLOOPPI
void loop(){
Ulo_MilliSek = millis(); // Luetaan sisäinen kello
// Painiketesti
Bol_StartPain = digitalRead(Con_StartPain);
digitalWrite(Con_LED_13, Bol_StartPain);

// LEDien ohjaus elohopeakytkimistä
Bol_Hg_Vas = !digitalRead(Con_Hg_Vas);
Bol_Hg_Oik = !digitalRead(Con_Hg_Oik);
digitalWrite(Con_LED_Vas, Bol_Hg_Vas);
digitalWrite(Con_LED_Oik, Bol_Hg_Oik);

// Aikojen käynnistys ja mittaus
if(Bol_StartPain == true && Seq_MittSek == 0){
Seq_MittSek = 1;
}
switch (Seq_MittSek) {
case 1: // Vasemman elohopeakytkimen odotus
if(Bol_Hg_Vas == true){
Ulo_AlkuVasen = Ulo_MilliSek;
delay(560); // Eliminoidaan pisaran pomppiminen
Seq_MittSek = 2;
}
break;
case 2: // Lasketaan vasen heilahdusaika
if(Bol_Hg_Vas == false){
Ulo_AikaVasen = Ulo_MilliSek - Ulo_AlkuVasen;
Seq_MittSek = 3;
}
break;
case 3: // Käynnistetään oikean heilahdusaika
if(Bol_Hg_Oik == true){
Ulo_AlkuOikea = Ulo_MilliSek;
delay(560); // Eliminoidaan pisaran pomppiminen
Seq_MittSek = 4;
}
break;
case 4: // Lasketaan oikea helahdusaika
if(Bol_Hg_Oik == false){
Ulo_AikaOikea = Ulo_MilliSek - Ulo_AlkuOikea;
Seq_MittSek = 5;
}
break;
case 5:
Fun_Tulostus();
Seq_MittSek =  0;  //jos haluaa vain kertatulostuksen
break;                    // uusi painaminen = seuraava tulostus
}

Int_PrintViive--;
if(Int_PrintViive == 0){
Fun_Tulostus();
Int_PrintViive = Con_PrintViive;
} // Tulostuskutsu loppu
delay(1);
} // Pääohjelma LOPPU

OHJELMA 26c
/***************************************
* Ohjelma26c
* 29.11.2016
* Modulin (KY-027) toiminnan testaus.
* c-versiossa muutetaan LEDien kirkkautta
* analogialähtöjen avulla (PWM)
**************************************/

// MÄÄRITTELYT:
// I/O-määrittelyt
const int Con_LED_Vas = 5;
const int Con_Hg_Vas = 2;
int Int_LED_Ohjaus = 0;
float Flo_LED_Ohjaus = 0.0;
float Flo_Muutos = 0.58;
boolean Bol_Hg_Vas = false;
const int Con_LED_Oik = 6;
const int Con_Hg_Oik = 3;
boolean Bol_Hg_Oik = false;
const int Con_StartPain = 4;
boolean Bol_StartPain = false;
const int Con_LED_13 = 13;

// Ajan mittauksen määrittely
unsigned long Ulo_MilliSek = 0;
unsigned long Ulo_AlkuVasen = 0;
unsigned long Ulo_AikaVasen = 0;
int Seq_MittSek = 0; // LEDien kirkkauden ohjaus

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_Hg_Vas, INPUT);
pinMode(Con_Hg_Oik, INPUT);
pinMode(Con_StartPain, INPUT);
pinMode(Con_LED_13, OUTPUT);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
Ulo_MilliSek = millis(); // Luetaan sisäinen kello
// Painiketesti
Bol_StartPain = digitalRead(Con_StartPain);
digitalWrite(Con_LED_13, Bol_StartPain);

// LEDien ohjaus elohopeakytkimistä
Bol_Hg_Vas = !digitalRead(Con_Hg_Vas);
Bol_Hg_Oik = !digitalRead(Con_Hg_Oik);

// Aikojen käynnistys ja mittaus
if(Bol_StartPain == true && Seq_MittSek == 0){
Seq_MittSek = 1;
}
switch (Seq_MittSek) {
case 1: // Vasemman elohopeakytkimen odotus
if(Bol_Hg_Vas == true ){
Ulo_AlkuVasen = Ulo_MilliSek;
delay(560); // Eliminoidaan pisaran pomppiminen
Seq_MittSek = 2;}
break;
case 2: // Lasketaan vasen heilahdusaika
if(Bol_Hg_Vas == false){
Ulo_AikaVasen = Ulo_MilliSek - Ulo_AlkuVasen;
Serial.print("Heilahdusaika :"); Serial.println(Ulo_AikaVasen);
Seq_MittSek = 3;}
break;
case 3: // Odotetaan uutta heilahdusta vasemmalle
Int_LED_Ohjaus = 0;
if(Bol_Hg_Vas == true ){
Seq_MittSek = 4;}
break;
case 4: // Vasen LED kirkastuu
analogWrite(Con_LED_Vas, Int_LED_Ohjaus);
Flo_LED_Ohjaus = Flo_LED_Ohjaus + Flo_Muutos;
Int_LED_Ohjaus = Flo_LED_Ohjaus;
Int_LED_Ohjaus = constrain(Int_LED_Ohjaus, 0, 255);
if(Int_LED_Ohjaus == 255){
Seq_MittSek = 5;}
break;
case 5: // Vasen LED himmenee
Flo_LED_Ohjaus = Flo_LED_Ohjaus - Flo_Muutos;
Int_LED_Ohjaus = Flo_LED_Ohjaus;
Int_LED_Ohjaus = constrain(Int_LED_Ohjaus, 0, 255);
analogWrite(Con_LED_Vas, Int_LED_Ohjaus);
if(Int_LED_Ohjaus == 0 && Bol_Hg_Oik == true ){
Seq_MittSek = 6;}
break;
case 6: // Oikea LED kirkastuu
analogWrite(Con_LED_Oik, Int_LED_Ohjaus);
Flo_LED_Ohjaus = Flo_LED_Ohjaus + Flo_Muutos;
Int_LED_Ohjaus = Flo_LED_Ohjaus;
Int_LED_Ohjaus = constrain(Int_LED_Ohjaus, 0, 255);
if(Int_LED_Ohjaus == 255){
Seq_MittSek = 7;}
break;
case 7: // Oikea LED himmenee
Flo_LED_Ohjaus = Flo_LED_Ohjaus - Flo_Muutos;
Int_LED_Ohjaus = Flo_LED_Ohjaus;
Int_LED_Ohjaus = constrain(Int_LED_Ohjaus, 0, 255);
analogWrite(Con_LED_Oik, Int_LED_Ohjaus);
if(Int_LED_Ohjaus == 0 && Bol_Hg_Vas == true ){
Seq_MittSek = 3;}
break;
} // Sekvenssi loppu
delay(1);
} // Pääohjelma LOPPU