Kytkentä on aika paljon
edellisen kaltainen. Nyt on tullut lisää toinen painike, toinen LED (valo) ja
LDR, valovastus (Light Dependent Resistor). Sen vastusarvo muuttuu sen mukaan,
miten paljon siihen osuu valoa. Mitä enemmän valoa, sitä pienempi vastus, ja
sitä suurempi jännite syntyy analogiatuloon ja muunnoksen jälkeen lukema monitoriin.
Ohjelmassa olikin ensin vain tuo valon mittausosa. Monitoroimalla analogiatuloa
A0, pääsi näkemään lukemat. Enpä huomannut laittaa niitä tarkasti ylös, mutta
peittämällä ja puristamalla valovastus, oli tulon lukema muutama kymmenen
(esim. 50) ja valaisemalla taskulampulla lukema oli 1000 paikkeilla. Kun lukema
on 512 (1023 / 2), on valovastuksen arvo 10 kilo-ohmia, sillä tuolloin 5V:in
jännite jakaantuu kahtia. Eppabasicilla voi laskea noiden ääripäiden vastusarvot.
Jokainen muunnoksen porras on 4,89mV (5000 / 1023) ja tästä saadaan laskettua valovastuksen
yli vaikuttava jännite.
Dim Jännite = Lukema * 0.00489
Print Jännite & (" V")
Dim Virta = Jännite / 10000
Print Virta & (" A")
Dim LDRjännite = 5 - Jännite
Print ("Jännite valovastuksen yli: ") & LDRjännite &
(" V")
Dim Vastus = LDRjännite / Virta / 1000
Print Vastus & (" kilo Ohmia")
Kun lukemaksi (= analogiatulon lukema monitoroinnissa) syöttää 50, saadaan tulokseksi 194,49 kolo-ohmia ja syötettäessä 1000, saadaan vastusarvoksi 0,2449 kilo-ohmia, eli 244,9 ohmia. Tuossa ohjelmassa virtaa laskettaessa luku 10.000 on vastus R3, eli analogiatulosta maapotentiaaliin. Sen arvo on 10 kohmia. Jos lukemaksi syöttää 511, saadaan vastuksen arvoksi melko tarkasti 10 kohmia. Jos tämä on valaistustilanne, jakaantuu syöttävä 5V:ia puoliksi LDR:n ja kuoritusvastuksen kesken.
Tätä ohjelmaa tehdessä ja
testatessa oli niin kirkas päivä, että valovastus piti peittää pienen
potentiometrin varjoon. Tätä sovellusta voi tietysti kehittää myös
monipuolisemmaksi. Porrasvaloissa on tyypillisesti ajastin, mikä sammuttaa
valon tietyn ajan kuluttua automaattisesti. Se on joskus huono, jos valot ovat
jo päällä, niin valo voi sammua kesken nousun (tai laskun). Pieni apu saattaisi
olla, jos valoviive alkaisi joka painalluksella alusta. Uimahallin suihkut
toimivat ajastimen kannalta juuri näin.
Tuo valoraja (400) on
otettu ihan vaan hihasta, mutta tuntui toimivalta. Samoin hystereesi (80). Hystereesi
on tärkeä, sillä jos vallitaan vain suurempi tai pienempi, niin toiminnasta
tulee hyvin epästabiili. Määrityksissä ei ole mitään erikoista, määritellään
sarjaliikenne monitorointia varten, kaksi lähtöä (OUTPUT) ja kaksi tuloa (INPUT).
Analogiatuloa (A0) ei tarvitse erikseen asettaa tuloksi, sillä sen pinni määräytyy
jo määrittelyissä
(int Int_AnaTulo = 0;). Analogiakäsittelyssä tulon lukemat rajoitetaan välille 100 .. 750
(constrain(Int_AnaTulo, 100, 750); Tämä käsky ei muuta lukemia miksikään, vaan ainostaan asettaa rajat. Aiemmin oli käytössä skaalauskäsky (map), millä koko tuloalue muutetaan toiseksi alueeksi. Esim: tulo 0 .. 1023 muutetaan lähtöalueelle 0 .. 255. MerkkiLEDiä ohjataan suoraan hämäräkytkimen sekvenssistä, mutta varsinaisen valon aliohjelmaa (Fun_Valo(boolean Tila) { .. }) kutsutaan kolmesta eri kohdasta pääohjelmaa.
(int Int_AnaTulo = 0;). Analogiakäsittelyssä tulon lukemat rajoitetaan välille 100 .. 750
(constrain(Int_AnaTulo, 100, 750); Tämä käsky ei muuta lukemia miksikään, vaan ainostaan asettaa rajat. Aiemmin oli käytössä skaalauskäsky (map), millä koko tuloalue muutetaan toiseksi alueeksi. Esim: tulo 0 .. 1023 muutetaan lähtöalueelle 0 .. 255. MerkkiLEDiä ohjataan suoraan hämäräkytkimen sekvenssistä, mutta varsinaisen valon aliohjelmaa (Fun_Valo(boolean Tila) { .. }) kutsutaan kolmesta eri kohdasta pääohjelmaa.
Ohjelma 12
/***************************************
*
Ohjelma 12
*
15.04.2016
*
Käytävävalo hämäräkytkimellä
**************************************/
// MÄÄRITTELYT:
// Kellon määrittely
unsigned long Ulo_MilliSek = 0;
unsigned long Ulo_UusiMilliSek = 0;
const long CoL_EroSekunti = 999;
int Int_Sekunti = 0;
boolean Bol_Tulosta = false; // Tulostus lopuksi pois
const int Con_AnaTulo = 0;
int Int_AnaTulo = 0;
const int Con_ValoRaja = 400;
const int Con_Hystereesi = 80;
const int Con_MerkkiLED = 3;
int Seq_Valo = 1; // Käynnistetään valaistuksen hallinta
const int Con_Valo = 4;
boolean Bol_Valo = false;
const int Con_Kytkin_1 = 2;
const int Con_Kytkin_1Viive = 3;
int Int_Kytkin_1Viive = 0;
boolean Bol_Kytkin_1Tila = false;
int Seq_Kytkin_1 = 0;
const int Con_Kytkin_2 = 5;
const int Con_Kytkin_2Viive = 7;
int Int_Kytkin_2Viive = 0;
boolean Bol_Kytkin_2Tila = false;
int Seq_Kytkin_2 = 0;
// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_MerkkiLED, OUTPUT);
pinMode(Con_Valo, OUTPUT);
pinMode(Con_Kytkin_1, INPUT);
pinMode(Con_Kytkin_2, INPUT);
}// Asetuksen loppu
// PÄÄLOOPPI Varsinainen suoritusosa. Jatkuva suoritus
void loop(){
// Sisäisen kellon käyttö
Ulo_MilliSek = millis();
if(Ulo_MilliSek - Ulo_UusiMilliSek
> CoL_EroSekunti){
Ulo_UusiMilliSek = Ulo_MilliSek;
Int_Sekunti++;
if(Bol_Tulosta ==
true){Fun_Tulostus();}
} // Kellon loppu
// Analogiatulon käsittely
Int_AnaTulo = analogRead(Con_AnaTulo);
Int_AnaTulo = constrain(Int_AnaTulo, 100, 750);
switch (Seq_Valo) {
case 1: // tämä (1) on vakio, siis
ei muuttuja
if(Int_AnaTulo < Con_ValoRaja){
Seq_Valo = 2;
}
break;
case 2:
// askel 2
digitalWrite(Con_MerkkiLED, HIGH);
Seq_Kytkin_1 = 1; // Kytkinsekvenssien käynnistys
Seq_Kytkin_2 = 1;
Seq_Valo = 3;
break;
case 3:
// askel 3
if(Int_AnaTulo > Con_ValoRaja + Con_Hystereesi){
digitalWrite(Con_MerkkiLED, LOW);
Seq_Kytkin_1 = 0; // Kytkinsekvenssien
lopetus
Seq_Kytkin_2 = 0;
Bol_Valo = false;
Fun_Valo(Bol_Valo);
Seq_Valo = 1; // paluu
askeleeseen 1
}
break;
} // Valo-sekvenssin loppu
// Kytkimien käsittely
Bol_Kytkin_1Tila = digitalRead(Con_Kytkin_1);
Bol_Kytkin_2Tila = digitalRead(Con_Kytkin_2);
// KYTKIMEN 1 -tilan käsittely, nouseva reuna
switch (Seq_Kytkin_1) {
case 1:
if (Bol_Kytkin_1Tila == true){ //
painiketta painettu
Int_Kytkin_1Viive ++;
if (Int_Kytkin_1Viive >
Con_Kytkin_1Viive){
Bol_Valo = !Bol_Valo;
Fun_Valo(Bol_Valo);
Int_Kytkin_1Viive = 0;
Seq_Kytkin_1 = 2;
}
}
break;
case 2:
if (Bol_Kytkin_1Tila == false){
Seq_Kytkin_1 = 1;
}
break;
} // Kytkin 1, sekvenssin loppu
// KYTKIMEN 2 -tilan käsittely, nouseva reuna
switch (Seq_Kytkin_2) {
case 1:
if (Bol_Kytkin_2Tila == true){
Int_Kytkin_2Viive ++;
if (Int_Kytkin_2Viive >
Con_Kytkin_2Viive){
Bol_Valo = !Bol_Valo;
Fun_Valo(Bol_Valo);
Int_Kytkin_2Viive = 0;
Seq_Kytkin_2 = 2;
}
}
break;
case 2:
if
(Bol_Kytkin_2Tila == false){
Seq_Kytkin_2 = 1;
}
break;
} // Kytkin 2, sekvenssin loppu
delay(1);
} // Pääohjelma LOPPU
// FUNKTIOT
void Fun_Tulostus(){
//Serial.print("Teksti :");
Serial.println(Muuttuja);
//Serial.print("Analogiatulon raaka arvo :"); Serial.println(Int_AnaTulo);
//Serial.print("Kytkin 1 tila :"); Serial.println(Bol_Kytkin_1Tila);
//Serial.print("Kytkin 1 seq :");
Serial.println(Seq_Kytkin_1);
}
void Fun_Valo(boolean Tila){
digitalWrite(Con_Valo, Tila);
} // Valo-aliohjeman loppu
Ei kommentteja:
Lähetä kommentti