Arduino
mikrokontrollereihin on tarjolla runsas valikoima erilaisia oheislaitteita ja
onneksi myös ohjelmia. Tarjolla on myös laaja valikoima kirjasto-ohjelmia,
joita voidaan sujuvasti liittää omiin ohjelmiin. Kaikkea ei tarvise tehdä itse.
Tämä jakso käsittelee kaksirivistä, 16 merkin LCD-näyttöä, minkä piirilevyyn on
sisälletty myös kuusi (6) ohjauspainiketta. LCD-näytön käyttöön tulee
Arduino-ohjelmiston mukana kirjasto-ohjelma LiquidCrystal.h,
mikä liitetään ohjelman alkuun (#include <LiquidCrystal.h>). Lisäksi
määritellään näytön käyttämät pinnit, mitkä vaihtelevat LCD-tyypin mukaan. Nyt
käyttämäni näyttö sopii suoraan työnnettäväksi UNO:n pinneihin. Painikkeet on
kytketty analogiatuloihin, ja niistä saadaan kustakin oma kokonaislukunsa, mikä
määrää sen, mitä on painettu.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyYfTJKCp5eG25MFSwLZ7jQ5LiqTd92kZQfaeztEtgRTwXEid113YIgqPlsqxYsIH-87MOO0jjo6VACN09zArLYxottrmWOUA2mTHlCa8ek8LWgS4RCcNDhV4LQrfNC91y6k_vM67fkn-E/s200/LCD+001p.jpg)
Toinen pääteema tässä
jaksossa on tehosyöttö. Tähän asti Arduino on saanut tehonsa (5V DC) USB-liitynnän
kautta. Kello pitää kuitenkin saada irti tietokoneesta. Analogiatulojen
vieressä sijaitsevat pinnit VIN, GND, GND, 5V, 3,3V ja RESET. Arduinolle voi
ulkopuolelta syöttää käyttöjännitettä 7 .. 12VDC. Joko tuon VIN-pinnin (+) kautta,
tai sitä varten olevan pistokeliittimen kautta (keskipiikki on +). Jännitteen
napaisuuden on oltava oikea, muutoin ardu voi tuhoutua. Tarkkana pitää olla
myös tulo- / lähtö-pinnien kanssa. Ne eivät kestä juurikaan ylijännitettä (EI
yli 5V). Nuo 5VDC ja 3,3VDC muodostetaan piirilevyllä ja on tarkoitettu
ulkopuolisten laitteiden syöttöjännitteeksi. Tällöinkin on huolehdittava siitä,
ettei kokonaiskulutus ylitä 400mA
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0bjV9WQo8Q9aXpU-HSavhq5tTeVHE9xV1RKJmjJtaTJ9hATvyHvPYzA6tqZ14C069ZFfy0m8yqurEkrk1jX1Xt1H_WF6QTZUhujtODgncDhq5PuTwehOMrkHuimoWRGbH_doPS6VzQFto/s200/LCD+002m.jpg)
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9zefpx-YSfRBuQXW52xKkVeTCRcZM8A6y-Z0NcEd0G7TmSE0TBHI-71yWalzDijH-RC7z-iSIbWM21NlneNQaRa85LAdNmvMXamddtwvMnaspuAwkm26-7pqpyyT3RZOFu7E9cUllmOf5/s200/LCD+004p.jpg)
Ohjelma 18
/*****************************************
* Ohjelma 18
* 27.04.2016
* LCD-näyttö kellonajoille:
* Uneversal 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 = 985;
int Int_Sekunti = 0;
int Int_Minuutti = 0;
int Int_Tunti = 0;
boolean Bol_Tulosta = false;
int Seq_YlaRivi = 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);
}// 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;
Int_Sekunti++;
if(Int_Sekunti > 59){
Int_Minuutti++;Int_Sekunti = 0;
lcd.setCursor(2, 1);
lcd.print(" ");}
if(Int_Minuutti > 59){
Int_Tunti++;Int_Minuutti = 0;
lcd.setCursor(2, 1);
lcd.prin("
"); }
if(Int_Tunti > 23){Int_Tunti = 0;
lcd.setCursor(2, 1);
lcd.prin("
"); }
if(Bol_Tulosta == true){Fun_Tulostus();}
}
lcd_key = read_LCD_buttons(); // Näytön painikkeet
// Näytön valintasekvenssi
switch (Seq_YlaRivi) {
case 1:
lcd.setCursorr(0, 0);
lcd.prin(" ");
lcd.setCursor(1, 0);
lcd.prin("UNIVERSAL TIME");
delay(20);
if(lcd_key == 4){Seq_YlaRivi = 2;
Int_Tunti = Int_Tunti +2;}
break;
case 2:
if(lcd_key == 5){Seq_YlaRivi = 3;}
break;
case 3:
lcd.setCursor(0, 0);
lcd.prin("
");
lcd.setCursor(3, 0);
lcd.prin("TALVIAIKA");
delay(20);
if(lcd_key == 4){Seq_YlaRivi = 4;
Int_Tunti = Int_Tunti +1;}
break;
case 4:
if(lcd_key == 5){Seq_YlaRivi = 5;}
break;
case 5:
lcd.setCursor(0, 0);
lcd.prin("
");
lcd.setCursor(3, 0);
lcd.prin("KESA-AIKA");
delay(20);
if(lcd_key == 4){Seq_YlaRivi = 6;
Int_Tunti = Int_Tunti -3;}
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.prin("0");
lcd.prin(Int_Tunti);
}else{lcd.prin(Int_Tunti);}
lcd.prin(":");
if(Int_Minuutti < 10){
lcd.prin("0");
lcd.prin(Int_Minuutti);
}else{lcd.print(Int_Minuutti);}
lcd.prin(":");
if(Int_Sekunti < 10){
lcd.prin("0");
lcd.prin(Int_Sekunti);
}else{lcd.prin(Int_Sekunti);}
// Tunnin asetus
switch (Seq_TuntiAsetus) {
case 1:
if(lcd_key == 3){
Kep_TuntiAs = true;
lcd.setCursor(0, 1);
lcd.prin("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.prin(" ");
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.prin("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.prin(" ");
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, 59);
Int_Minuutti = constrain(Int_Minuutti, 0, 59);
Int_Tunti = constrain(Int_Tunti, 0, 59);
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;
}
Muutama sana ohjelmasta.
Alun määrittelyjä määrää aika paljon kirjasto-ohjelma. Muutenkin monia
toimintoja on kopioitu netistä löytyvistä esimerkeistä. Ylärivin
kirjoitusosiossa olevat 20ms viiveet (delay82)
rauhoittavat näyttöä. Painikkeiden luvun aliohjelma ei ole nyt void,vaan tyyppiä int, koska se palauttaa (return)
painiketta vastaavan kokonaisluvun. Muutoin ohjelma on varsin tyypillistä
sekvensseillä toteutettuja suoritusnauhoja.