/*
"CW Drill" 2018 feb 06 XRQTechLab Shig
reference sketch : cw_trainer_jan27c JH7UBC Keiji Hata Thanks!!
Arduino uno and LCD shield + piezoSP + Variable resistance

*/

#define SP_PIN 1//圧電スピーカーを接続するピン
#define freq 800//トーン(Hz)
/*
Pin seting
D1: Tone out
A0: select button lcd sheild
A1: morse speed timer set
A2: random seed
A3: Vcheck Low Voltage Alarm
*/

#include <LiquidCrystal.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
//const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
const int rs = 8 , en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


//各文字に対するモールスコード(短点0、長点1、ストップビット1 例 A=00000110=6)
byte mcode[36] = {6,17,21,9,2,20,11,16,4,30,13,18,7,5,15,22,27,10,8,3,12,24,14,25,29,19,63,62,60,56,48,32,33,35,39,47};
byte mcode3[47] = {59,6,12,61,34,18,37,24,29,31,53,43,55,46,23,5,20,22,58,36,10,21,16,27,28,17,51,19,2,9,25,52,3,49,41,14,57,7,8,11,45,15,26,13,42,4,44};
int m = 0; //文字のコード
int y = 0; //モールス符号送出時のビット0の値
int val = 0;//入力した値
int n; //文字数
int interval1;
int interval2;
int x = 0;

void HRBT(){ // HR HR BTの送出
lcd.clear();
lcd.setCursor(0 ,0);
lcd.print("ABC.. Random");
HR();
HR();
// BT の送出
m=9;
morseTone();
m=15;
morseTone();
delay(interval2 *2);
lcd.clear();
}

void HR(){
// lcd.print("HR ");
m=16;
morseTone();
delay(interval1);
m=10;
morseTone();
delay(interval1);
}

void AR(){ //
m=42;
morseTone();
delay(interval1);
}

void SN(){ // ラタ
m=40;
morseTone();
delay(interval1);
}

void rndChar(){ // ABC 80字をランダムに送出する
int count=0; //カウンタクリア

while (count <80){

int x = random(n); //randum code
m = mcode[x];
morseTone(); //morsecode out
delay(interval1); //wait
if( x < 26 ) {(x = x + 65); }
else {( x = x + 22);}
lcd.write(x); // lcd print
lcd.print(" ");
if (( (count+1) % 8) ==0){ //8文字ごとにcheck
delay(2000);
lcd.clear() ;
WPM();
lcd.setCursor(0, 1);
}
count++;
}
AR();
delay(3000);
lcd.clear();
}

void morseTone(){ //モールス符号を送出する
int dottime = analogRead(1) / 5;
int dashtime = dottime * 3;
interval1 = dottime * 2;
interval2 = dottime * 4;

while (m != 1){
y = m & 1;
if (y == 0){
tone(SP_PIN,freq,dottime);
delay(interval1);
} else{
tone(SP_PIN,freq,dashtime);
delay(interval2);
}
m = m >> 1;//1bit 右にシフト
}
}

void WPM(){
lcd.setCursor(0, 0);
lcd.print("WPM ");
lcd.print(2400 / interval1);

}

void HRDO(){ // HR HR ホレの送出
lcd.clear();
lcd.setCursor(0 ,0);
lcd.write(220); //ワ
lcd.write(204); //ブ
lcd.write(222); //
lcd.write(221); //ン
lcd.print(".. Random");
HR();
HR();
m=9; //D
morseTone();
m=15; //O
morseTone();
delay(interval2 *2);
lcd.clear();
}

void rndChar2(){ //カナ 8字をランダムに送出する
int count=0;//カウンタクリア
while (count < 80){
x = random(n);
m = mcode3[x];
morseTone();
int kana =(x +177);
delay(interval1);
lcd.write(kana);
lcd.print(" ");
if (( (count+1) % 8) ==0){ //8文字ごとにcheck
delay(2000);

lcd.clear();
WPM();
lcd.setCursor(0,1);
}
count++;
}
SN();
delay(3000);
lcd.clear();
}

// set up the LCD's number of columns and rows:
void setup(){
randomSeed(analogRead(2));
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("CW Drill! ver1.0");
lcd.setCursor(0, 1);
lcd.print(" XRQ TechLab");
delay (2000);
lcd.clear();
};


void loop(){
if (analogRead(0) >1000){
// other setting
lcd.setCursor(0,0);
WPM();
lcd.print(" waiting!!");
lcd.setCursor(0,1);
lcd.print("Please set MODE");
delay(1000);
}

else if (analogRead(0)<10){
// kana loop
HRDO();
n=47;
WPM();
lcd.setCursor(0, 1);
rndChar2();
}

else {
// ABC loop
HRBT();
n=36;
WPM();
lcd.setCursor(0, 1);
rndChar();
}
}