tiistai 12. huhtikuuta 2016

Kosketinvärähtely sekä switch ... case - rakenne


Käytännössä monia toimintoja ohjataan painikkeilla tai kytkimillä. Aina kun mekaaniset koskettimet ”lyövät” yhteen, värähtelevät koskettimet muutaman kerran. Monissa tapauksissa siitä ei ole haittaa, koska tuo tarkoittaa paria värähdystä millisekuntien aikana, mutta tuo ominaisuus on tarpeen eliminoida, varsinkin silloin, kun ohjaus tapahtuu kytkimen nousevalla reunalla ( kytkin suljetaan) tai laskevalla reunalla ( kytkin avataan). Kytkentäkaava on hyvin yksinkertainen. Siinä on painike, LED ja pari vastusta.

Esimmäisessä ohjelmassa ei tarvitse ottaa värähtelyä huomioon, sillä LED palaa, kun painiketta painetaan. Tuo alasvetovastus, mihin painike kytkee 5V:n jännitteen on merkitty 10 kilo’ohmia ( = 10 000 ohmia), mutta se voi hyvin olla väliltä 4,7 kohm .. 15 kohm. Tuloa D2 ei voi kuitenkaan jättää vapaaksi, ”ilmaan”, sillä silloin syntyy häiriöitä. Toinen mahdollisuus on asetuksissa määritellä Arduinon sisäinen ylösvetovastus. Tässä tapauksessa painike kytketään pinnistä D2 maihin ja toiminta on päinvastainen kuin yllä olevassa kytkennässä.

Ohjelma 9
/***************************************
 *  Ohjelma 9
 *  12.04.2016
 *  Painikkeen käsittely
 **************************************/
// MÄÄRITTELYT:
const int Con_Painike = 2;
const int Con_LEDout = 3;
boolean Bol_Painike = false;

// ASETUKSET:
void setup(){                 
pinMode(Con_Painike, INPUT);
pinMode(Con_LEDout, OUTPUT);
}// Asetuksen loppu
// PÄÄLOOPPI Varsinainen suoritusosa. Jatkuva suoritus

void loop(){
Bol_Painike = digitalRead(Con_Painike);
digitalWrite(Con_LEDout, Bol_Painike);
delay(1);
} // Pääohjelma LOPPU

Seuraavat kaksi ohjelmaesimerkkiä käyttävät samaa kytkentää kuin tuo edellinen ohjelmakin. Ero on toiminnallinen. Ohjelmassa 10 LED syttyy ja sammuu, kun painike painetaan alas. Tämä on nouseva reuna, sillä jännite kontrollerin digitaalitulossa (D2) nousee 0V -> 5volttiin, eli digitaalitila muuttuu nollasta (0) ykköseksi (1). Ohjelmassa 11 LED syttyy ja sammuu painike päästettäessä. Tämä on laskeva reuna, sillä tulo muuttuu ykkösestä nollaksi (1 -> 0).

Tällaiset toiminnat voidaan tehdä myös if else –rakenteilla tallentamalla edellinen tila sekä tekemällä mutkikkaampia ehtoja ja vertailuja, mutta huomattavasti näppärämpi on
switch (var) { case 1: … break; case 2: break; ……. dafault; } ( kytke (muuttuja) { tapaus 1: seis; tapaus 2: … seis; jne. oletus: … }. If-rakenteessa ohjelma käy läpi kaikki vaihtoehdot ja suorittaa ne, joiden kohdalla ehto täyttyy. Switch-rakenteessa suoritetaan ainoastaan tarpeellinen. Se ensinnäkin yksinkertaistaa ohjelma rakennetta, ja ennen kaikkea nopeuttaa ohjelma suoritusta, koska tarpeeton ohjelmarivien ”kelaaminen” jää pois. Tämä on myös tapa rakentaa suoritusnauhoja, jolloin tärkeämpiä asioita käydään läpi tiheämmässä tahdissa ja hitaampaa tarvetta suoritetaan harvemmin. Käsky millis() on tässäkin mielessä tärkeä toiminto, sillä ohjelmien osat saadaan täten synkronoitua reaaliaikaan. Jos tämä kappale vaikuttaa ”vaahtoamiselta”, niin se on todella sitä, sillä tämä rakenne on yksi tärkeimmistä ohjelmointityökaluista.

Mutta ensin LEDin sytytys ja sammutus painikkeen ohjaamana.

Ohjelma 10
/***************************************
 *  Ohjelma 10
 *  13.04.2016
 *  LEDin tilan vaihto nousevasta reunasta
 **************************************/

// MÄÄRITTELYT:
const int Con_Painike = 2;
const int Con_LEDout = 3;
const int Con_PainikeViive = 3;
boolean Bol_PainikeTila = false;
boolean Diu_PainikeTila = false; // Nouseva reuna
boolean Did_PainikeTila = false; // Laskeva reuna
int Int_PainikeViive = 0;
int Seq_OhjausUp = 1;

// ASETUKSET:
void setup(){                  
 Serial.begin(9600);         
 pinMode(Con_Painike, INPUT);
  pinMode(Con_LEDout, OUTPUT);
}// Asetuksen loppu

// PÄÄLOOPPI Varsinainen suoritusosa. Jatkuva suoritus
void loop(){
// Luetaan digitaalitulo 
Bol_PainikeTila = digitalRead(Con_Painike);

// KOSKETTIMEN-tilan käsittely, nouseva reuna
switch (Seq_OhjausUp) {
  case 1:
    if (Bol_PainikeTila == true){
      Int_PainikeViive ++;
        if (Int_PainikeViive > Con_PainikeViive){
          Diu_PainikeTila = !Diu_PainikeTila;
          Fun_LedOut(Diu_PainikeTila);
          Int_PainikeViive = 0;
          Seq_OhjausUp = 2;
        }
    }
    break;
  case 2:
    if (Bol_PainikeTila == false){
          Seq_OhjausUp = 1;
        }
    break;
}
delay(1);
} // Pääohjelma LOPPU

// FUNKTIOT
void Fun_LedOut(boolean Tila){
  digitalWrite(Con_LEDout, Tila);

}

Ohjelma 11 äskeinen toiminta, mutta nyt laskevasta reunasta.

Ohjelma 11
/***************************************
 *  Ohjelma 11
 *  13.04.2016
 *  LEDin tilan vaihto laskevasta reunasta
 **************************************/

// MÄÄRITTELYT:
const int Con_Painike = 2;
const int Con_LEDout = 3;
const int Con_PainikeViive = 3;
boolean Bol_PainikeTila = false;
boolean Diu_PainikeTila = false; // Nouseva reuna
boolean Did_PainikeTila = false; // Laskeva reuna
int Int_PainikeViive = 0;
int Seq_OhjausDn = 1;

// ASETUKSET:
void setup(){                 
 Serial.begin(9600);         
 pinMode(Con_Painike, INPUT);
 pinMode(Con_LEDout, OUTPUT);
}// Asetuksen loppu

// PÄÄLOOPPI Varsinainen suoritusosa. Jatkuva suoritus
void loop(){
// Luetaan digitaalitulo 
Bol_PainikeTila = digitalRead(Con_Painike);

// KOSKETTIMEN-tilan käsittely, laskeva reuna
switch (Seq_OhjausDn) {
  case 1:
    if (Bol_PainikeTila == true){
      Int_PainikeViive ++;
        if (Int_PainikeViive > Con_PainikeViive){
          Int_PainikeViive = 0;
          Seq_OhjausDn = 2;
        }
    }
    break;
  case 2:
    if (Bol_PainikeTila == false){
         Did_PainikeTila = !Did_PainikeTila;
          Fun_LedOut(Did_PainikeTila);
          Seq_OhjausDn = 1;
        }
    break;
}
delay(1);
} // Pääohjelma LOPPU

// FUNKTIOT
void Fun_LedOut(boolean Tila){
  digitalWrite(Con_LEDout, Tila);

}

Ei kommentteja:

Lähetä kommentti