torstai 29. joulukuuta 2016

”TerveysTutka”, versio 0.0

Aikamoinen johtohässäkkä.
Tässä sovelluksessa on käytössä moduulit KY-039 (sydämen lyönnin indikaattori) ja KY-013 (termistorilla toteutettu lämpötila-anturi). Näyttönä on SUNTAI SC.2002A2BLYY-W kaksirivinen ja 20 merkkipaikkainen LCD-näyttö. Pääasia ei tietenkään ole terveyden tarkkailu, vaan pieni ohjelmasovellus näihin ihmisen ja moduuleiden rajapintaan. Esimerkki sydämen sykinnästä on videolla antinarduvideo31.youtube.com.
Tuo LCD-näyttö on jo varsin vanhaa ja poistuvaa tyyppiä. Sitä on kuitenkin jäänyt roikkumaan Yleiselektroniikka Oy:n hyllylle. Jäljellä olevat näytöt myydään pilkkahintaan. Kannattaa hyödyntää ne pois. Ei kirpaise niin pahasti, jos tuhoutuu kokeilussa.
 
Tämä LCD-näyttömalli ei sisällä ”ääkkösiä”, joten ne on ladattava kirjastoon (#LiquidCrystal.h) erikseen. Pienet ä ja ö sisältyvän tämän näytön kirjastoon, samoin kuin asteen merkki, mutta eivät kuitenkaan ole aivan samat, mitä ASCII-taulukko osoittaa. Suuret Ä ja Ö pitää muodostaa ja ladata aivan erikseen, piste pisteeltä, kuten myöskin ”sydämen imu- ja puristusvaiheet”. Noita isoja ääkkösiä ei tässä tekstissä tarvita.
     Tuo lämpötila-anturi (KY-013) perustuu NTC-termistoriin (NTC = Negative Temperature Coefficient = negatiivinen lämpötilakerroin), minkä vastus siis pienenee lämpötilan kasvaessa. Vastuksen muutos EI ole lineaarinen lämpötilan muutokseen nähden. Tässä sovelluksessa mittausta EI ole linearisoitu. Ohjelmassa on mittaus ja näyttö kalibroitu kahdessa pisteessä: 1. mittausta verrattu huoneen lämpötilaan ja säädetty näyttämään samaa. 2. Anturilla on mitattu ihon lämpötila = ”kainalokalibrointi” (37C). On mahdollista, että nuo pisteet ovat melko tarkkoja, mutta muut lämpötilat heittävät enemmän tai vähemmän.
     Anturissa KY-039 on IR-LEDi osoittamassa valotransistoria (tässä myös IR-alueelle herkkä) kohti. Infrapunasäteily tunkeutuu näiden kahden komponentin väliin laitetun sormen läpi. Veren erilainen määrä sormen päässä muuttaa säteilyn intensiteettiä, joten mooduulin lähdöstä on saatavissa vastaava signaali. Valotransistoriin vaikuttaa myös ympäristö. Siksi sovelluksessa on kaksi kondensaattoria, joilla pitkittäin olevalla erotetaan anturin antama tasajännite (pohjalukema) sekä hitaat muutokset. (Ohjelmallisesti en onnistunut sauodatuksessa.) Poikittain oleva pienempi kondensaattori suodattaa nopeat, esim. huoneen valaistuksen ym. häriöt. Sen rinnalla on 100 kilo-ohmin purkausvastus. Aikavakiot sopivat sydämen lyöntirytmiin. Täten on mahdollista saada sydämen kuvio sykkimään lyöntien tahtiin. Signaali on varsin pieni – muutaman kymmenen millivoltin luokkaa. Onneksi kuitenkin ja luotan vakaasti, että SOTE-porukalla tulee olemaan oleellisesti korkeatasoisemmat tutkimusvälineen kuin tässä esittämäni.
Moduulien ja LCD-näytön kytkentä Arduinoon
Ohjeman aluksi määritellään ja tuodaan kirjasto: #include <LiquidCrystal.h>. Seuraavana kirjastomoduulille kerrotaan ohjausbitit. Ne eivät välttämättä tarvitse olla juuri nuo, mutta niiden järjestys on oleellinen. Sitten kirjastolle määritellään binääritietoina ä, ö ja aste. Ne löytyvät näytön ominaisuuksista. Sitten kaksi kahdeksan (8) bitin binääritaulukkoa, joilla kirjastolle määritellään sydämen näytön kaksi tilaa.
     Näiden jälkeen muiden muuttujien määrittelyt ja aliohjelmat. Asetuksissa kirjoitetaan vakiotekstit, ja täten vain kerran. Sydänkuvio, lyöntinopeus sekä lämpötila päivitetään omille kohdilleen ohjelman aikana.
     Ohjelman aluksi mitataan sisäistä aikaa (millis()) ja lasketaan lämpötila. Sydämen lyönnin valvonta koostuu kolmen askeleen sekvenssistä. Sekvenssi odottaa sykettä askeleessa 1. Kun sellainen havaitaan analogiatulossa, talletetaan tämä aikalukema askeleessa 1 ja siirrytään askeleeseen 2 odottamaan uutta sykäystä. Kun se on tullut, talletetaan sykkeiden väliaika ja hypätään askeleeseen 3. Siellä lasketaan ja muunnetaan väliaika sydämenlyönneiksi minuutissa, sekä päivitetään tämä ja lämpötilan lukema näyttöön. Sekvenssi hyppää takaisin askeleeseen yksi odottamaan seuraavaa lyöntiä.
Viimeisenä ohjelmassa on muutama lause, joilla pienen viiveen jälkeen palauttetaan sydänkuvio ”imutilaan”.

OHJELMA 31
/**************************************
* Ohjelma 31
* 28.12.2016
* Kehon lämpötila ja sydänpulssit
**************************************/
// MÄÄRITTELYT:
   #include <LiquidCrystal.h>
   LiquidCrystal lcd(12, 11, 5, 4,3,2);

   const byte api = B11100001; // ä
   const byte opi = B11101111; // ö
   const byte ast = B11011111; // aste
   byte Syd1[8] = // Sydämen reunat
                           {B00000,B00000,B01010,B10101,
                           B10001,B10001,B01010,B00100};
   byte Syd2[8] = // Sydämen sisus
                           {B00000,B00000,B00000,B01010,
                           B01110,B01110,B00100,B00000};
   int i = 0;

// Ajastukset
   unsigned long Ulo_MilliSek = 0;
   unsigned long Ulo_EdellinenMilliSek = 0;
   const int Con_Kierrokset = 40;
   unsigned int Unt_Kierrokset = 0;
   int Int_Kierrokset = 0;
   boolean Bol_Aika = false;

// Sydän-määritykset
   const int Con_Pulssi = A1;
   int Int_PulssiRaaka = 0;
   unsigned int Unt_SykeVali = 0;
   float Flo_PulsPerMin = 0;
   unsigned int Unt_Pulssit = 0;
   boolean Bol_SydSyk = false;
   int Seq_Syke = 1;

// Lämpötilan mittaus
   const int Con_LampAnturi = A0;
   int Int_LampoRaaka = 0;
   float Flo_LampoTila = 0.0;

// ALIOHJELMAT
// Sydämen syke näyttöön
   void Fun_Sydan(int i){
      lcd.setCursor(10,0);
      lcd.print(" ");
      lcd.write(i);
   }// Syke loppu

// Pulssit näyttöön
   void Fun_Pulssit(int p){
      lcd.setCursor(13,0);
     lcd.print(p);
   }

//Lämpötila näyttöön
   void Fun_Lampo(float t){
      lcd.setCursor(11,1);
      lcd.print(t);
      lcd.setCursor(15,1);
      lcd.write(ast);
      lcd.print("C");
   }

// ASETUKSET:
   void setup(){
      Serial.begin(9600); // Sarjaliikenteen alustus
      lcd.createChar(0,Syd1); // Sydämen reunat
      lcd.createChar(1,Syd2); // Sydämen sisus
      lcd.begin(20,2);
      lcd.clear();
// Tekstit näyttöön, suoritetaan kerran
      lcd.setCursor(0, 0);
      lcd.print("Syd");
      lcd.write(api);
      lcd.print("nly");
      lcd.write(opi);
      lcd.print("n:         p/min");
      lcd.setCursor(0, 1);
      lcd.print("L");
      lcd.write(api);
      lcd.print("mp");
      lcd.write(opi);
      lcd.print("tila:");
   }// Asetuksen loppu

// PÄÄLOOPPI
   void loop(){
      Ulo_MilliSek = millis();
      Int_LampoRaaka = analogRead(Con_LampAnturi);
      int Temp = constrain((335 - Int_LampoRaaka), 0, 100);
      Flo_LampoTila = 22.7 + 0.17 * Temp;
      Int_PulssiRaaka = analogRead(Con_Pulssi);
      if(Int_PulssiRaaka > 2){
            Bol_SydSyk = true;
            if(Seq_Syke == 1) {Bol_SydSyk = true;}
      } // Pulssin mittaus loppu

// Sydän supistuu
      switch (Seq_Syke) {
            case 1:
                  if(Bol_SydSyk == true){
                        Ulo_EdellinenMilliSek = Ulo_MilliSek;
                        Bol_SydSyk = false;
                        delay(300);
                  Seq_Syke = 2;
                  }
            break;
            case 2:
                  if(Int_PulssiRaaka > 2){
                        Unt_SykeVali = Ulo_MilliSek - Ulo_EdellinenMilliSek;
                        Unt_SykeVali = constrain(Unt_SykeVali, 10, 2999);
                        Bol_SydSyk = false;
                  if(Unt_SykeVali < 3000){
                        Seq_Syke = 3;
                  }}
            break;
            case 3:
                  Flo_PulsPerMin = 1000.0 / Unt_SykeVali * 60.0;
                  Unt_Pulssit = Flo_PulsPerMin;
                  Unt_Pulssit = constrain(Unt_Pulssit, 20, 99);
                  i = 1;
                        Fun_Sydan(i);
                        Fun_Pulssit(Unt_Pulssit);
                        Bol_SydSyk = false;
                        Fun_Lampo(Flo_LampoTila);
                  Seq_Syke = 1;
                  break;
            }// Sekvenssi loppu

// Sydän avautuu
      Unt_Kierrokset++;
      if(Unt_Kierrokset > Con_Kierrokset){
            Bol_SydSyk = false;
            i = 0;
            Fun_Sydan(i);
            Unt_Kierrokset = 0;} // Kierroslaskuri loppu

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

tiistai 20. joulukuuta 2016

Alien hyökkäys KY-038, KY-006 ja KY-008

Vasemmalta: laser, mikki, "sireeni"
Tässä jaksossa kohteena on kolme moduulia: 1. Äänianturi (KY-038), missä mikrofonin signaali vahvistetaan ja siirrtetään lähtöön sekä analogisena että bibäärisignaalina (viime mainittua en testannut), 2. pietsoelementtisummeri (KY-006), mitä voidaan ohjata eri korkuisilla äänisignaaleilla (PWM-lähtö. Pinnit D3 ja D11 ovat tone-käskylle mahdollisia), sekä 3. laser-moduuli (KY-008), mikä lähettää punaista koherenttia valoa. Viimeksi mainitussa liitosmerkinnät olivat väärin päin. Oheisessa kaaviossa toimivalla tavalla korjattuna. (Moduulissa siis Arduinon lähtö (+) kytketään KY-008 miinus (-) merkittyyn pinniin ja maa (GND) signaali (S) pinniin.

Taistelukaverit
Ohjelma on varsin yksinkertainen. Se koostuu kolmesta askeleesta: ensimmäisessä askeleessa luetaan äänisignaalia. Mikäli se ylittää tai alittaa annetulla määrällä (tässä 5) setup:issa luetun pohjatason, sekvenssi siirtyy askeleeseen 2. Askeleessa kaksi kasvatetaan ohjelmakierrosten lukumäärää annettuun rajaan saakka. Näistä ohjelmakierroksista muodostetaan jakojäännös (modulo, käsky on %). Jos jakojäännös on nolla (0), vilkutetaan laseria ja signaloidaan sireeniä. Tuo jakojäännöksen käyttö on helppo tapa saada nuo kaksi signaalia toimimaan saman aikaisesti, mutta eri tahtiin. Kun kierroslaskuri ylittää annetun maksimiarvon (Con_Kierrokset = 2800;), siirtyy ohjelma askeleeseen kolme. On tärkeää, että askelissa kaksi (2) ja kolme (3) ei tutkita mikrofonipiiriä, jotta se ei herätä laseria ja sireeniä uudestaan, vaan ainoastaan ulkoinen ääni. Askeleessa kolme (3) on samaa tarkoitusta varten myös 0,1 sekunnin viive. Ilman sitä kytkentä käynnistää itse itsensä.
Edellä pari kuvaa: kokeilukytkentä sekä ”parhaat kaverukset”. Torjuntataistelu ja ohjelman toiminta näkyvät parhaiten videosta antinarduvideo30.youtube.com. Videolla tosin “sireenin” ääni (melkein seireenin) on niin vaimea, että se ei kylläkään havahduta ketään näinkään kauheassa ihmiskuntaan kohdistuvassa tilanteessa!

ps. Ei tuo laser pysäyttänyt hyökkääjää. Ratkaisu löytyi Alien niskasta: ON-OFF-kytkin!

OHJELMA 30
/***************************************
* Ohjelma 30
* 20.12.2016
* Alien hyökkäys ja torjunta
**************************************/

// MÄÄRITTELYT:
// Ajastukset
const int Con_Kierrokset = 2800;
int Int_Kierrokset = 0; // Ohjelmakierroslaskuri
const int Con_LaserRytmi = 100;
const int Con_SireeniRytmi = 400;
// Muuttujamäärittelyt
const int Con_MikkiTulo = 0;
int Int_MikkiPohja = 0;
int Int_MikkiArvo = 0;
int Int_Herkkyys = 5;
const int Con_Laser = 2;
boolean Bol_Laser = false;
const int Con_Sireeni = 3;
boolean Bol_Sireeni = false;
unsigned int Unt_YlaTaajuus = 750;
unsigned int Unt_AlaTaajuus = 350;
int Seq_Torjunta = 1;

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_Laser, OUTPUT);
Int_MikkiPohja = analogRead(Con_MikkiTulo);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
switch (Seq_Torjunta) {
case 1:
Int_MikkiArvo = analogRead(Con_MikkiTulo);
if(Int_MikkiArvo > Int_MikkiPohja + Int_Herkkyys
|| Int_MikkiArvo < Int_MikkiPohja - Int_Herkkyys){
Seq_Torjunta = 2;
}
break;
case 2:
Int_Kierrokset++;
if(Int_Kierrokset % Con_SireeniRytmi == 0){
Bol_Sireeni = !Bol_Sireeni;}
if(Bol_Sireeni == false){
tone(Con_Sireeni, Unt_YlaTaajuus);
}else{
tone(Con_Sireeni, Unt_AlaTaajuus);
}
if(Int_Kierrokset % Con_LaserRytmi == 0){
Bol_Laser = !Bol_Laser;
digitalWrite(Con_Laser, Bol_Laser);
}
if(Int_Kierrokset > Con_Kierrokset){
Seq_Torjunta = 3;}
break;
case 3:
noTone(Con_Sireeni);
delay(100);
Int_Kierrokset = 0;
Bol_Sireeni = false;
Bol_Laser = false;
digitalWrite(Con_Laser, Bol_Laser);
Seq_Torjunta = 1;
break;
}

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

lauantai 17. joulukuuta 2016

Pyörivä kooderi KY-040 ja 3-värin LED KY-009

Tämä ohjelma valottaa lähinnä kooderin (KY-040) käyttöä. Se on nykyään korvannut säädettävän potentiometrin monissa tehtävissä, kuten esim. audiolaitteiden voimakkuuden säätiminä. Potentiometreissä vastuksen muodostanut hiilikarvo kuluu ajan oloon asentoa muutettaessa, ja ikääntyneeseen laitteeseen alkaa tulla rahinaa.

Kuva 1. Kooderimoduuli.
Tällaisessa kooderissa tieto kiertosuunnasta ja kulman suuruudesta muodostetaan reiällisen koodilevyn ja optoerottimien avulla. Periaatteessa siten, että LEDi lähettää valoa (tai infrapunaa) ja fotodiodi (tai fototransistori) ottaa signaalin vastaan rakojen toisella puolella. Siinä on joko kaksi rei'itystä, joiden kohdistuskulmat poikkeavat hiukan toisistaan, tai kaksi optoryhmää hiukan eri kulmissa. Kumpiko menetelmä on tässä käytössä; en tiedä. Aiheeseen voi tutustua tarkemmin, kun eteen tulee aikansa palvellut tietokonehiiri. Sen rullassa koodataan myös suunta ja määrä.

 
Kuva 2. LED-moduuli
3-väriLEDissä (KY-009) on sininen (B), punainen(R) ja vihreä (G) valo. Moduuli toimi, mutta merkinnät (-, R, G, B) olivat väärässä järjestyksessä. Virhe on sekä netin kuvassa että todellisuudessa (siis ainakin tämän ysikön kohdalla). Toimiva järjestys näkyy oheisesta kytkentäkaaviosta.


Kuva 3. Tämän ohjelman laitekytkentä.
Kuva 4.
Kooderissa KY-040 on seuraavat merkinnät: GND (maa eli miinus (-)), + (+5V DC), SW (kytkin, mikä oikosulkee pinnin maahan. Toimii painamalla nuppia), DT (data, mikä seuraa akselin kiertymistä) ja CLK (kello, mikä seuraa akselin kiertymistä). Varsinainen informaatio saadaan siis pinneistä DT ja CLK.






Kuva 5. DT ja CLK aktiivisia.
Kierrettäessä akselia myötäpäivään, menee DT-pinni ensin nollaan (siksi ohjelmassa on käänteinen tilan luku: Bol_DT = !digitalRead(Con_DT);), sitten molemmat (DT ja CLK), ja edelleen käännettäessä DT-pinni nousee ensin ykköseksi ja sen jälkeen CLK-pinni. Käännettäessä vastapäivään, järjestys on tietysti päinvastainen.






OHJELMASTA
Tässä ohjelmassa nämä (suunnat) erotellaan 6-askelisella sekvenssillä (Seq_Suunta). Myötäpäivään käännettäessä sekvenssi käynnistetään askeleesta yksi (1) ja vastapäivään kierrettäessä askeesta neljä (4). Näiden kummankin tapauksen pääteaskeleessa (3 ja 6) sekvenssi sammutetaan (Seq_Suunta saa arvon nolla (0)). Varsinaiset toiminta- ja ohjausaskeleet ovat ne (1 ja 4), missä molemmat (DT ja CLK) ovat aktiivisia. Riippuen halutusta kiertosuunnasta, käynnistetään vastaava LEDien kirkkautta ja järjestystä ohjaava sekvenssi (Seq_LEDitMyota tai Seq_LEDitVasta ). Samalla sammutettaan vastakkaisen suunnan sekvenssi.

LEDien kirkkauden ohjaus (PWM) suoritetaan näissä suuntasekvensseissä. Ensin LEDi kirkastuu täyteen kirkkauteen, minkä jälkeen himmenee nollaan. Sitten vaihtuu LEDi ja sama toistuu. Myötäsuuntaan järjestys on: sin → pun → vih ja vastasuuntaan sin → vih → ja pun.
     Tähän asti kaikki hyvin. Parissa kohtaa jouduin taipumaan Arduinon omaani voimakkaampaan tahtoon. Tavoitteenani oli, että suunnan vaihto tapahtuu samalla värillä ja jatkaa siitä väristä ja kirkkaudesta, mihin toiminta edellisellä kiertosuunnalla jäi. Nyt vaihto tapahtuu aina sinisen LEDin nousevasta kirkkaudesta (siis sekvenssin alusta). En jaksanut pitkään puurtaa tämän ongelman parissa, sillä ajan ja energian vei toinen ongelma, virhetoiminto, mikä myös jäi ohjelmaan. Jos vaihto tapahtuu muun kuin sinisen LEDin kohdalla, jää muun värinen LED palamaan pohjalle, kunnes sen värin askeleet on käyty kerran läpi uuden suunnan ohjauksella. Ei auttanut, vaikka muihin väreihin kirjoitti nollaa (0), ei mikään muukaan kokeilemistani variaatioista. Varmaan tässä olisi hyvä projekti tulevaisuuteen, projekti, mikä lähestyy ratkaisua ainoastaan tuon ongelman näkökulmasta.
Kuva 6. Ohjelman mukainen versio.
     Kirkkauden lisäksi muutosnopeutta voidaan säätää kooderin painikkeella, mikä toimii painamalla kiertoakselia. Pohjalukema on 15 (analogialähtö, 8 bittiä, alue 0 .. 255, PWM - ohjaus). Jokainen painikkeen päästäminen kasvattaa muutosnopeutta 15:llä. Kun ylitetään luku 60, palataan takaisin pohja-arvoon 15. Vihreä LEDi oli lisäksi huomattavasti kirkkaampi kuin kaksi muuta. Siksi sitä ohjataan jakamalla ohjausarvo kolmella (3).



Alla olevasta ohjelmasta on karsittu pois kaikki ohjelmakehityksen aikaiset kokeilut ja lisät (esim. Selial.print muutujien arvojen tulostamiseksi ruudulle). Aluksi tutkin pelkän kooderin toimintaa (Kuvat 4 ja 5). Siinä oli ainoastaan LEDit ilmaisemassa kooderin pinnien tilaa sekä suuntien tilaa. Sen vaiheen toimintaa havainnoi myös suttuinen video (antinarduvideo29a. youtube.com)
     Ohjelmasta on karsittu myös edellä mainitsemani virheen ja toiminnan kokeilut. Toinen video (antinarduvideo29b. youtube.com) antaa jonkinlaisen kuvan ratkaisun toiminnasta. Siitä pystyy myös hiukan näkemään suunnanvaihdossa tapahtuvan virheen; edellisen LEDin jäämisen palamaan (värit eivät ole puhtaita, vaan sekoittuvat).

OHJELMA 29
/***************************************
* Ohjelma 29
* 15.12.2016
* Ohjataan kolmen LEDin kirkkautta
* kahteen suuntaan neljällä eri
* nopeudella
**************************************/

// MÄÄRITTELYT:
boolean Bol_MyotaSuunta = false;
boolean Bol_VastaSuunta = false;
const int Con_CLK = 2; // Kooderin kello
boolean Bol_CLK = false;
const int Con_DT = 3; // Kooderin data
boolean Bol_DT = false;
const int Con_LEDsin = 9;
boolean Kep_LEDsin = false;
const int Con_LEDpun = 10;
boolean Kep_LEDpun = false;
const int Con_LEDvih = 11;
boolean Kep_LEDvih = false;
int Int_OhjausArvo = 0;
int Int_LedOhjaus = 0; // LEDeille menevä analogia-arvo
int Int_Muutos = 15; // Muutosnopeutta voihetaan painikkeella
const int Con_Kytkin = 4; // Kooderin painikkeen tulo
boolean Bol_Kytkin = false;
int Int_KykinViive = 0;
int Seq_kytkin = 1;
int Seq_Suunta = 0;
int Seq_LEDitMyota = 0;
int Seq_LEDitVasta = 0;

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_Kytkin, INPUT_PULLUP); // Sisäinen ylösveto
pinMode(Con_CLK, INPUT);
pinMode(Con_DT, INPUT);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
Bol_Kytkin = !digitalRead(Con_Kytkin);
switch (Seq_kytkin) {
case 1: // tämä on vakio
if(Bol_Kytkin == true){
Int_KykinViive++;
if(Int_KykinViive > 7){
Int_KykinViive = 0;
Seq_kytkin = 2;
}
}
break;
case 2:
if(Bol_Kytkin == false){
Int_Muutos = Int_Muutos + 15;
if(Int_Muutos > 60){
Int_Muutos = 15;
}
Seq_kytkin = 1; }
break;
} // Kytkinsekvenssi loppu

Bol_CLK = !digitalRead(Con_CLK);
Bol_DT = !digitalRead(Con_DT);

// Kiertosuunnan määrittely
if(Bol_DT == true && Bol_CLK == false && Seq_Suunta == 0){
Seq_Suunta = 1;}
if(Bol_CLK == true && Bol_DT == false && Seq_Suunta == 0){
Seq_Suunta = 4;}

switch (Seq_Suunta) {
case 1:
if(Bol_DT == true && Bol_CLK == true){
Int_OhjausArvo = Int_OhjausArvo + Int_Muutos;
Int_OhjausArvo = constrain(Int_OhjausArvo, 0, 255);
if(Seq_LEDitMyota == 0){
Seq_LEDitMyota = 1;
Seq_LEDitVasta = 0;
}
Seq_Suunta = 2;
}
break;
case 2:
if(Bol_DT == false && Bol_CLK == true){
Seq_Suunta = 3;
}
break;
case 3:
if(Bol_DT == false && Bol_CLK == false){
Seq_Suunta = 0;
}
break;
case 4:
if(Bol_CLK == true&& Bol_DT == true){
Int_OhjausArvo = Int_OhjausArvo + Int_Muutos;
Int_OhjausArvo = constrain(Int_OhjausArvo, 0, 255);
if(Seq_LEDitVasta == 0){
Seq_LEDitVasta = 1; // Vastasuuntanen käynnistetään
Seq_LEDitMyota = 0; // Myötäsuuntanen lukitaan
}
Seq_Suunta = 5;
}
break;
case 5:
if(Bol_CLK == false && Bol_DT == true){
Seq_Suunta = 6;
}
break;
case 6:
if(Bol_CLK == false && Bol_DT == false){
Seq_Suunta = 0;
}
break;
} // Suunta-sekvenssin loppu

// LEDien ohjaus myötäpäivään sin -> pun -> vih -> sin jne.
switch (Seq_LEDitMyota) {
case 1: // sininen kirkastuu
analogWrite(Con_LEDvih, 0);
Kep_LEDsin = true;
Int_LedOhjaus = Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Seq_LEDitMyota = 2;
}
break;
case 2: // sininen himmenee
Int_LedOhjaus = 255 - Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Kep_LEDsin = false;
Seq_LEDitMyota = 3;
}
break;
case 3: // punainen kirkastuu
analogWrite(Con_LEDsin, 0);
Kep_LEDpun = true;
Int_LedOhjaus = Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Seq_LEDitMyota = 4;
}
break;
case 4: // Punainen himmenee
Int_LedOhjaus = 255 - Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Kep_LEDpun = false;
Seq_LEDitMyota = 5;
}
break;
case 5: // vihreä kirkastuu
analogWrite(Con_LEDpun, 0);
Kep_LEDvih = true;
Int_LedOhjaus = Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Seq_LEDitMyota = 6;
}
break;
case 6: // vihreä himmenee
Int_LedOhjaus = 255 - Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Kep_LEDvih = false;
Seq_LEDitMyota = 1;
}
break;
}// Myötäsekvenssi loopu

// LEDien ohjaus vastapäivään sin -> vih -> pun -> sin jne.
switch (Seq_LEDitVasta) {
case 1: // sininen kirkastuu
analogWrite(Con_LEDpun, 0);
Kep_LEDsin = true;
Int_LedOhjaus = Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Seq_LEDitVasta = 2;
}
break;
case 2: // sininen himmenee
Int_LedOhjaus = 255 - Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Kep_LEDsin = false;
Seq_LEDitVasta = 5;
}
break;
case 3: // punainen kirkastuu
analogWrite(Con_LEDvih, 0);
Kep_LEDpun = true;
Int_LedOhjaus = Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Seq_LEDitVasta = 4;
}
break;
case 4: // punainen himmenee
Int_LedOhjaus = 255 - Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Kep_LEDpun = false;
Seq_LEDitVasta = 1;
}
break;
case 5: // vihreä kirkastuu
analogWrite(Con_LEDsin, 0);
Kep_LEDvih = true;
Int_LedOhjaus = Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Seq_LEDitVasta = 6;
}
break;
case 6: // vihreä himmenee
Int_LedOhjaus = 255 - Int_OhjausArvo;
if(Int_OhjausArvo == 255){
Int_OhjausArvo = 0;
Kep_LEDvih = false;
Seq_LEDitVasta = 3;
}
break;
}// Vastasekvenssi loppu

// LEDien ohjaukset
if(Kep_LEDsin == true){
analogWrite(Con_LEDsin, Int_LedOhjaus);}
if(Kep_LEDpun == true){
analogWrite(Con_LEDpun, Int_LedOhjaus);}
if(Kep_LEDvih == true){
analogWrite(Con_LEDvih, Int_LedOhjaus / 3);}
delay(1);
} // Pääohjelma LOPPU