Morsetuksen alkeita.
Tämä ohjelma on oikeastaan vain runko sähkötyksen opetteluun. Tämä sisältää ainoastaan aakkosmerkit, jotka muodostuvat yhdestä, kahdesta tai kolmesta, joko pisteestä tai viivasta. Pisteistä lyhin on E-kirjain, eli yksi lyhyt piste. Viivoista lyhyin on T-kirjain. Pisin merkki on O-kirjain, joka muodostuu kolmesta viivasta. Muut ovat niiden väliltä ja muodostuvat pisteistä ja viivoista.
Tavoite luonnollisesti oli tehdä tämä ohjelma, sekä luoda siihen erilaisia toimintoja. Kun ohjelma käynnistyy, tulostuu näytölle pyyntö painaa kosketuspainiketta TCH1 ja valita sähkötyksen nopeus. Nopeus voidaan valita potentiometrilla, ja ainoastaan silloin, kun sormi viipyy painikkeella. Kun sormi irrotetaan, tulostuu näytölle ilmoitus, että sähkötys alkaa kahden sekunnin kuluttua.
Kun sähkötysääni kuuluu, on näyttö tyhjä. Tänä aikana kuuluu ainoastaan summerista sähkötysmerkit. Viiden merkin välein on hiukan pidempi tauko. Merkkejä arvotaan 30 kappaletta (rajoite johtuu tuosta pienestä kaksirivisestä näytöstä). Kun sähkötys on loppu, tulostetaan näytölle kahteen riviin nuo arvotut sähkötysmerkit. Jos merkit on kirjoitettu paperille kuuntelun aikana, voidaan niiden oikeellisuus ja oppimisen onnistuminen tarkastaa näytöltä.
Kun painiketta TCH1 painetaan uudestaan, voidaan nopeus valita jälleen (ei välttämätöntä), ja suorittaa uusi harjoitus. Tuo nopeusasetus (15 .. 93 merkkiä minuutissa) on lähinnä symbolinen, sillä kaikkia sähkötysmerkkejä tämä harjoitus ei sisällä. Tavoite on ainoastaan, että voidaan muodostaa sekä hidasta että nopeaa sähkötystä.
/***************************************
* Ohjelman nimi: Opi_CWF_64* 26.09.2023
* Lyhyt toimintaselostus:
* Tulostaa pillille 1, 2, ja 3
* merkkisiä sähkötyskirjaimia.
* Sähkötysnopeutta voidaan säätää käsin.
**************************************/
// MÄÄRITTELYT:
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 13,12,11,10);
const byte api = B11100001; // ä
const byte opi = B11101111; // ö
// Taulukoita ja muuttujia
const int Con_Tapit = 30; // Merkkitaulukon pituus
char Merkit[] = "EISTANMUDORKWG"; // Arvottavat merkkialkiot
String Tulos = "";
int Int_TaulPit = 13; // Merkkien lukumäärä
int Int_Sattuma = 0;
const int ViKe = 5; // Viivekerroin
boolean Kep_Tulosta = false; // Tulostus LCD-näytölle
int Int_Rivi = 0; // LCD-näytön rivi
int Int_Kohta = 0; // LCD-näytön kohta
// Liityntöjen määrittelyt
// Digitaalinen tulo
const int Con_TCH1 = 3; // Kosketuspainike 1
// Digitaalinen lähtö
const int Con_Pilli = 9; // tämä on BUZZeri
// Analoginen tulo
const int Con_Nopeus = 0; // Potentiometrin tulo
int Int_NopRaaka = 0;
int Int_Nopeus = 0; // sähkötyksen nopeussäätö
const int Con_Arpa = 1;
// Sähkötykseen ja ohjaukseen liittyvät
int Int_Jakso = 0; // Tähän lasketaan nopeus
boolean Bol_TCH1 = false;
boolean Diu_TCH1 = false; // Painiketieto yhden kierroksen ajan
boolean Kep_teksti_1 = true; // Alkutekstin kirjoitus
// Sekvenssit
int Seq_TCH1 = 1; // Kosketuspainikkeen käsittely
int Seq_CW_Merkit = 0; // Merkkien valinta taulukosta
//********************************************************************
// ALIOHJELMAT
// Näytön aliohjelmat
void Fun_Tyhjenna(int rivi){
lcd.setCursor(0, rivi);
lcd.print(" ");
}// LCD rivityhjennys loppu
// Tekstien päivitys
void Fun_Teksti(int kohta, int rivi, char teksti){
lcd.setCursor(kohta, rivi);
lcd.print(teksti);
}// Teksti_ali loppu
void Fun_Lause(int kohta, int rivi, String teksti){
lcd.setCursor(kohta, rivi);
lcd.print(teksti);
}// Lause_ali loppu
//Numeroiden päivitys
void Fun_Nopeus(int kohta, int rivi, int nopeus){
lcd.setCursor(kohta, rivi);
lcd.print(nopeus);
}// Mittaus_ali loppu
// Äänimerkin aktivointi
void Fun_Pilli(int kertaa, int kesto){
int k = kertaa;
int pituus = Int_Jakso * kesto;
for(int i = 1; i <= k; i++){
digitalWrite(Con_Pilli, true);
delay(pituus);
digitalWrite(Con_Pilli, false);
delay(Int_Jakso);
}// Pillin loppu
}// foorin loppu
//********************************************************************
// ASETUKSET:
void setup(){
Serial.begin(9600);
lcd.begin(20,2);
lcd.clear();
Int_TaulPit = sizeof(Merkit);
randomSeed(analogRead(Con_Arpa));
pinMode(Con_TCH1, INPUT); // Kosketuspainike
pinMode(Con_Nopeus, INPUT); // Potentiometrin tulo
pinMode(Con_Pilli, OUTPUT);
}// Asetuksen loppu
//********************************************************************
// PÄÄLOOPPI
void loop(){
// Tyhjennetään näyttö ja ladataan alkutekstit
if (Kep_teksti_1 == true){
Fun_Lause(1, 0, "Paina TCH1 ja");
Fun_Lause(1, 1, "valitse nopeus");
Kep_teksti_1 = false;}
// Kosketuspainikkeen hallinta
Bol_TCH1 = digitalRead(Con_TCH1);
switch (Seq_TCH1) { // Kosketuspainikkeen sekvenssi
case 1:
if(Bol_TCH1 == true){
Fun_Tyhjenna(0);Fun_Tyhjenna(1);
Seq_TCH1 = 2;
}
break;
case 2:
Fun_Lause(1, 0, "Valitse nopeus:");
Seq_TCH1 = 3;
break;
case 3: // Määritellään sähkötysnopeus
Bol_TCH1 = digitalRead(Con_TCH1);
// Määritellään sähkötyksen nopeus ja merkin kesto
Int_NopRaaka = analogRead(Con_Nopeus);
Int_Nopeus = Int_NopRaaka / 13 + 15; //13 + 20;
Int_Jakso = 150 - Int_Nopeus; // Sähkötyksen nopeus potikalta
Fun_Nopeus(3,1,Int_Nopeus);
Fun_Lause(6,1,"m/min");
if(Bol_TCH1 == false){
Fun_Tyhjenna(0);Fun_Tyhjenna(1);
Seq_TCH1 = 4;}
break;
case 4: // Ilmoitus alkamisesta
Fun_Lause(1,0,"S");
Fun_Teksti(2,0,B11100001);
Fun_Lause(3,0, "hk");
Fun_Teksti(5,0,B11101111);
Fun_Lause(6,0, "tys alkaa");
Fun_Lause(3,1, "2s kuluttua.");
delay(2000);
Fun_Tyhjenna(0);Fun_Tyhjenna(1);
Seq_TCH1 = 5;
break;
case 5: // Aktivoidaan sähktyssekvenssi
Diu_TCH1 = true;
Seq_TCH1 = 6;
break;
case 6: // Tulostetaan näytölle arvotut merkit
Int_Rivi = 0;Int_Kohta = 0;
for(int k = 0; k < 30; k++){
Fun_Teksti(Int_Kohta, Int_Rivi, Tulos[k]);
Int_Kohta++;
if(Int_Kohta == 5 || Int_Kohta == 11){
Int_Kohta++;}
if(Int_Kohta == 17){Int_Rivi = 1; Int_Kohta = 0;}
} // forin loppy
Seq_TCH1 = 7;
break;
case 7: // Paluu uuteen arvontaan
Bol_TCH1 = digitalRead(Con_TCH1);
if(Bol_TCH1 == true){Seq_TCH1 = 1;}
Tulos = "";
break;
}// Sekvenssin loppu
if(Diu_TCH1 == true){// eka on lkm. ja toka kesto
for(int i = 0; i < Con_Tapit;i++){
Int_Sattuma = random(0,14);
Seq_CW_Merkit = Int_Sattuma;
Tulos = Tulos + Merkit[Int_Sattuma];
switch (Seq_CW_Merkit){
case 0:Fun_Pilli(1, 1);delay(ViKe*Int_Jakso);break; // E
case 1:Fun_Pilli(2, 1);delay(ViKe*Int_Jakso);break; // I
case 2:Fun_Pilli(3, 1);delay(ViKe*Int_Jakso);break; // S
case 3:Fun_Pilli(1, 2);delay(ViKe*Int_Jakso);break; // T
case 4:Fun_Pilli(1, 1);Fun_Pilli(1, 2);delay(ViKe*Int_Jakso);break; // A
case 5:Fun_Pilli(1, 2);Fun_Pilli(1, 1);delay(ViKe*Int_Jakso);break; // N
case 6:Fun_Pilli(1, 2);Fun_Pilli(1, 2);delay(ViKe*Int_Jakso);break; // M
case 7:Fun_Pilli(2, 1);Fun_Pilli(1, 2);delay(ViKe*Int_Jakso);break; // U
case 8:Fun_Pilli(1, 2);Fun_Pilli(2, 1);delay(ViKe*Int_Jakso);break; // D
case 9:Fun_Pilli(3, 2);delay(3*Int_Jakso);break; // O
case 10:Fun_Pilli(1, 1);Fun_Pilli(1, 2);Fun_Pilli(1, 1);delay(ViKe*Int_Jakso);break; // R
case 11:Fun_Pilli(1, 2);Fun_Pilli(1, 1);Fun_Pilli(1, 2);delay(ViKe*Int_Jakso);break; // K
case 12:Fun_Pilli(1, 1);Fun_Pilli(1, 2);Fun_Pilli(1, 2);delay(ViKe*Int_Jakso);break; // W
case 13:Fun_Pilli(1, 2);Fun_Pilli(1, 2);Fun_Pilli(1, 1);delay(ViKe*Int_Jakso);break; // G
}// Sekvenssin loppu
if(i > 0 && (i+1)%5 == 0){delay(10*Int_Jakso);}// Pidempi tauko viiden välein
}// Merkkivalinnan loppu
}// Arvonnan loppu
Diu_TCH1 = false; // DifUpp nollataan joka kierroksella
Kep_Tulosta = false;
delay(1);
} // Pääohjelma LOPPU