torstai 28. huhtikuuta 2016

LCD-kello, UT, talviaika ja kesäaika

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.
Tässä sovelluksessa painikkeella SELECT valitaan UT (yleisaika Universal Time), talviaika ja kesäaika. Nämä kiertävät tässä järjestyksessä jokaisella painamisella. Teksti on näytön ylärivillä. Seuraava painike on LEFT. Sen painamisesta alemman rivin vasempaan laitaan ilmestyy t-kirjain. Se merkitsee sitä, että painikkeilla UP kasvaa tuntilukema yhdellä (1) ja painikkeella DOWN vähenee yhdellä (Huom! EI kierrä nollan kautta edelliseen vuorokauteen). Vastaavasti painamalla RIGHT, ylös- ja alas-painikkeet vaikuttavat minuuttilukemaan. Vasempaan laitaan merkiksi tulee m-kirjain. Uudelleen painaminen (LEFT ja RIGHT) vapauttavat toiminnon. Samoin jos tuntimuuton on aktiivinen, minuutin painaminen vapauttaa tunnit. Ja päinvastoin. Kun kumpikaan ei ole aktiivinen, vaikuttavat ylös- ja alas-painikkeet sekuntilukemaan. Vaikka mikrokontrolleri on kideohjattu, on niiden aikatarkkuudessa yksilöllisiä eroja, joten oikeaa käyntinopeutta joutuu hiukan hakemaan. Hyvä apu siihen on teksti TV, missä on myös sekuntilukemat. Arvoa CoL_EroSekunti  joutuu hiukan hakemaan. Kun löytää mahdollisimman tarkan käyntinopeuden, voi helposti sekunteja korjata tarpeen mukaan. Jos on halua, voi sen tehdä tietysti automaattiseksikin.

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

Arduinoa voi syöttää esim. 9V nappiparistolla. Sen kapasiteetti on kuitenkin melko pieni, joten se tyhjenee varsin pian. Parempi on 6kpl AA-paria, joista muodostuu myös 9V. Nämä kestävät jo pidempään. Yksi hyvä vaihtoehto on pieni akku, mutta sen jännite ylittä ladattaessa 12V, joten väliin pitää sijoitta stabilisaattoripiiri (esim LM7809 tai LM7808 tai vastaava). Siitä hiukan myöhemmin.


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.

sunnuntai 24. huhtikuuta 2016

Ääni, tone(pin, taajuus), noTone()

Arduinoilla voidaan muodostaa myös melodioita. Varsinaisen soittimen ominaisuuksia siitä ei sinänsä löydy, mutta jotain yksinkertaista ja ehkä parhaimmillaan hälytys ja huomiosignaaleja. Käytettävissä eri sävelkorkeuksien tuottamiseen ovat käytettävissä ne pinnit, jotka tukevat analogialähtöinä (PWM). Pulssisuhde on 50% ja voimakkuutta ei voida suoraan säätää. Tämä koskee Arduinon digitaalilähtöä, mutta sen jälkeenhän signaali voidaan johtaa säädettävään vahvistimeen. Jos haluaa leikkiä Ardulla, voi voimakkuutta säätää esim. edellisen jakson LED / LDR-yhdistelmällä kytkemällä valovastus sarjaan toisen vastuksen kanssa ja muuttamalla LDR:n vastusarvoa valon voimakkuudella. Tämä toimii tavallaan potentiometrinä. Normaalin potentiometrin voi tietysti kytkeä digitaalilähtöön ja säätää sillä voimakkuutta.
Nyt on jo takana niin monta kännykkäsukupolvea, että korvakuulokkeita on varmaankin jäänyt roikkumaan laatikoihin. Ne käyvät sellaisenaan kytkettäväksi DO-pinniin. Ääni on aika karkeaa, koska se on suorakulma, eli ns. kanttiaaltoa. Se sisältää runsaasti harmonisia.
Alla sävelten taajuudet (Hz):

Kokonuotit: C = 262, D = 294, E = 330, F = 349, G = 392, A = 440, H = 494
Ylennetyt;    Cy = 277, Dy = 311, Fy = 370, Gy = 415, Ay = 466
Alennetut:   Da = 277, Ea = 311, Ga = 370, Aa = 415, Ha = 466

Tuo vahvennettu nuotti on yksiviivainen A. Nyt joku tarkkakorva sanoo, että ei pidä paikkaansa, ja on aivan oikeassa. Yllä olevat taajuudet on pyöristetty lähempää kokonaislukuun, sillä käsky tone() käsittelee ainoastaan etumerkitöntä integeriä (unsigned int). Oktaavit alaspäin kohti bassoja saadaan jakamalla kunkin nuotin taajuus kahdella (2). Vastaavasti oktaavi ylöspäin saadaan kertomalla aina edellisen oktaavin nuotit kahdella.

Tuo kaiutin näyttää varmaankin aika oudolta. Koska Arduinot on tarkoitettu ottamaan vastaan ulkoa signaaleja ja ohjelman käsittelyn jälkeen ohjaamaan ulkoisia laitteita, valitsin tuollaisen lapsille tarkoitetun kokeilusarjan MEHANO 153. Siinä on 153 erilaista sähköön liittyvää koetta. Se ei ole kovinkaan kallis, mutta silti sen avulla voi todella hyvin havainnoida erilaisten laitteiden, kuten moottoreiden ym. ja tässä tapauksessa kaiuttimen toimintaa. Äänisignaali johdetaan suojavastuksen (220 ohm) kautta käämille. Käämin sisällä on rautasydän ja sinisen ”kupin” sisällä on ohut rautainen kalvo. Kun Arduinosta johdetaan sähkösignaali käämiin, syntyy siihen ja sen sisällä olevaan rautasydämeen magneettikenttä, mikä saa kalvon värähtelemään signaalin tahdissa. Syntyy ääni. Tällä periaatteella toimivat kaikki dynaamiset kaiuttimet ja kuulokkeet. Tosin järjestys on toinen. Kela on kiinni kalvossa ja sijaitsee voimakkaassa, pysyvässä magneettikentässä. Vaihtovirta kelassa saa kelan ja kalvon värähtelemään äänen tahdissa. Tämä kokeilusarjan kaiutin ei ole mitään Hi Fi – luokkaa ja ääni on (onneksi) niin hiljainen (5V:n ohjauksella), että se ei häiritse ketään.
Oli melkoisen vaikeaa saada kalvo tarpeeksi lähelle (noin < 0,5mm) rautasydäntä. Tämä oli tarpeen, jotta ääni edes kuuluisi. Siinä oli hiukan virittelemistä ja viritellyn näköinenhän tuo toki onkin.




Seuraavassa parin kappaleen ohjelmat: Ensiksi monen nokkahuilistin ensimmäinen kappale ja toiseksi melodia elokuvasta Kummisetä. Ukko Noasta nousee esiin sekvenssin etu; samanlaisia jaksoja ei tarvitse kirjoittaa ohjelmaan moneen kertaan, vaan voi hyppiä ohjelmassa edestakaisin.

Ohjelma 16
/***************************************
 *  Ohjelma_16
 *  25.04.2016
 *  UKKO NOA
 **************************************/

// MÄÄRITTELYT:
// Nuotit
unsigned int Uin_C = 262; unsigned int Uin_D = 294;
unsigned int Uin_E = 330; unsigned int Uin_F = 349;
unsigned int Uin_G = 392; unsigned int Uin_A = 440;
unsigned int Uin_H = 494;

// Muut määrittelyt
int Int_Vali = 40;          // Tauko nuottien välissä
int Int_NV = 4;             // Nuotista toiseen väli
int Int_KokoNuotti = 1500;  //Kokonuotin kesto
const int Con_Pin = 3;      // Pinni mihin soitetaan
int Seq_UkkoNooa = 1;
boolean Bol_Kertaus = false;

// ASETUKSET:
void setup(){                  // Alustetaan muuttujat sekä määritellään I/O-tyyppi
 Serial.begin(9600);           // Alustetaan sarjaliikennne testiä varten
}// Asetuksen loppu

// PÄÄLOOPPI  Varsinainen suoritusosa. Jatkuva suoritus
void loop(){
switch (Seq_UkkoNooa) {
  case 1: Fun_Soita(Uin_C, 4, 3); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 2: Fun_Soita(Uin_E, 4, 1); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 3: Fun_Soita(Uin_D, 4, 3); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 4: Fun_Soita(Uin_F, 4, 1); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 5: Fun_Soita(Uin_E, 4, 2); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 6: Fun_Soita(Uin_D, 4, 2); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break
  case 7:
    Fun_Soita(Uin_C, 1, 1); delay(Int_Vali / Int_NV);
      if(Bol_Kertaus == false){Seq_UkkoNooa++;
      }else{Seq_UkkoNooa = 14;}
  break;
  case 8: Fun_Soita(Uin_E, 4, 4); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 9: Fun_Soita(Uin_G, 2, 1); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 10: Fun_Soita(Uin_F, 2, 1); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break
  case 11: Fun_Soita(Uin_D, 4, 4); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 12: Fun_Soita(Uin_F, 2, 1); delay(Int_Vali / Int_NV); Seq_UkkoNooa++; break;
  case 13:
    Fun_Soita(Uin_E, 2, 1); delay(Int_Vali / Int_NV);
      Bol_Kertaus = true;
      Seq_UkkoNooa = 1;
  break
  case 14: 
    delay(2000); Seq_UkkoNooa = 1; Bol_Kertaus = false;
  break;
}
delay(1);
} // Pääohjelma LOPPU

// FUNKTIOT
void Fun_Soita(unsigned int Nuotti, int Kesto, int Kertaa){
  for(int i = 0; i < Kertaa; i ++){
    tone(Con_Pin, Nuotti);
    delay(Int_KokoNuotti / Kesto);
    noTone(Con_Pin);
    delay(Int_Vali);
  } // For-osan loppu
} // Funktion loppu

Ohjelma 17
/* ************************************
 *  Ohjelma 17
 *  25.04.2016
 *  Speak softly, Love
 ***************************************/
 
// MÄÄRITTELYT:
// Nuotit
unsigned int Uin_C = 262; unsigned int Uin_D = 294;
unsigned int Uin_E = 330; unsigned int Uin_F = 349;
unsigned int Uin_G = 392; unsigned int Uin_A = 440;
unsigned int Uin_H = 494;

// Ylennetyt
unsigned int Uin_Cy = 277; unsigned int Uin_Dy = 311;
unsigned int Uin_Fy = 370; unsigned int Uin_Gy = 415;
unsigned int Uin_Ay = 466;

// Alennetut
unsigned int Uin_Da = 277; unsigned int Uin_Ea = 311;
unsigned int Uin_Ga = 370; unsigned int Uin_Aa = 415;
unsigned int Uin_Ha = 466;

// Muut määrittelyt
int Int_Vali = 40;          // Tauko nuottien välissä
int Int_NV = 4;             // Nuotista toiseen väli
int Int_KokoNuotti = 2500;  //Kokonuotin kesto
const int Con_Pin = 3;      // Pinni mihin soitetaan
int Int_Hyppy = 1;
int Seq_LoveMe = Int_Hyppy;
boolean Bol_Kertaus = false;
int Oktaavi = 1;

// ASETUKSET:
void setup(){                 
 Serial.begin(9600);          
}// Asetuksen loppu

// PÄÄLOOPPI          
void loop(){
// Nuotti, kesto, kertaa, oktaavi
switch (Seq_LoveMe) {
  case 1: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 2: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 3: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 4: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 5: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 6: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 7: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 8: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 9: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 10: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 11: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 12: Fun_Soita(Uin_A, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 13: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 14: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 15: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 16: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 17: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 18: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 19: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 20: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 21: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 22: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 23: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 24: Fun_Soita(Uin_Aa, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 25: Fun_Soita(Uin_G, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 26: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 27: Fun_Soita(Uin_G, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 28: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 29: Fun_Soita(Uin_Cy, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 30: Fun_Soita(Uin_E, 2, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 31: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 32: Fun_Soita(Uin_G, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 33: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 34: Fun_Soita(Uin_Cy, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 35: Fun_Soita(Uin_D, 2, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 36: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 37: Fun_Soita(Uin_D, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 38: Fun_Soita(Uin_F, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 39: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 40: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 41: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 42: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 43: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 44: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 45: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 46: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 47: Fun_Soita(Uin_Cy, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 48: Fun_Soita(Uin_D, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 49: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 50: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 51: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 52: Fun_Soita(Uin_Da, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 53: Fun_Soita(Uin_C, 2, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 54: Fun_Soita(Uin_E, 4, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 55: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 56: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 57: Fun_Soita(Uin_A, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 58: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 59: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 60: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 61: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 62: Fun_Soita(Uin_G, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 63: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 64: Fun_Soita(Uin_G, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 65: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 66: Fun_Soita(Uin_Gy, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 67: Fun_Soita(Uin_A, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 68: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 69: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 70: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 71: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 72: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 73: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 74: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 75: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 76: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 77: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 78: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 79: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 80: Fun_Soita(Uin_A, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 81: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 82: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 83: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 84: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 85: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 86: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 87: Fun_Soita(Uin_F, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 88: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 89: Fun_Soita(Uin_E, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 90: Fun_Soita(Uin_D, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 91: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 92: Fun_Soita(Uin_Aa, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 93: Fun_Soita(Uin_G, 2, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 94: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 95: Fun_Soita(Uin_G, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 96: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 97: Fun_Soita(Uin_Cy, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 98: Fun_Soita(Uin_E, 2, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 99: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 100: Fun_Soita(Uin_G, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 101: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 102: Fun_Soita(Uin_Cy, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break
  case 103: Fun_Soita(Uin_D, 2, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 104: noTone(Con_Pin); delay(Int_KokoNuotti / 8); Seq_LoveMe++; break;
  case 105: Fun_Soita(Uin_D, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 106: Fun_Soita(Uin_F, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 107: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 108: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 109: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 110: Fun_Soita(Uin_C, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 111: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 112: Fun_Soita(Uin_Ha, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 113: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 114: Fun_Soita(Uin_A, 8, 1, 1); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 115: Fun_Soita(Uin_Cy, 8, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 116: Fun_Soita(Uin_D, 1, 1, 2); delay(Int_Vali / Int_NV); Seq_LoveMe++; break;
  case 117: delay(2000); Seq_LoveMe = Int_Hyppy; break;
}

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

// FUNKTIOT
void Fun_Soita(unsigned int Nuotti, int Kesto, int Kertaa, int Oktaavi){
  for(int i = 0; i < Kertaa; i ++){
    tone(Con_Pin, Nuotti * Oktaavi);
    delay(Int_KokoNuotti / Kesto);
    noTone(Con_Pin);
    delay(Int_Vali);
  } // For-osan loppu
} // Funktion loppu