//******************************************************
// ATtiny 402 Project
// Morse code Metronom 40-200tempo
// XRQTechLab 20240914
//******************************************************

#include <EEPROM.h>

#define TempoUP_PIN 0
#define TempoDWN_PIN 1
#define LED_PIN 2
#define PIEZO_PIN 3
#define BUTTON_PIN 4

int tempo = 60; // 初期テンポ
int tempoChangeRate = 1; // テンポの変化量
bool settingMode = false;
unsigned long lastButtonPress = 0;
bool buttonPressed = false;
int pressStage = 0;
bool longPress = false;

void setup() {
pinMode(TempoUP_PIN, INPUT_PULLUP);
pinMode(TempoDWN_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(PIEZO_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
tempo = EEPROM.read(0); // EEPROMからテンポを読み込む
if (tempo < 40 || tempo > 200) tempo = 60; // 範囲外の場合は初期値に設定
}

void loop() {
if (digitalRead(BUTTON_PIN) == LOW) {
if (!buttonPressed) {
buttonPressed = true;
lastButtonPress = millis();
pressStage = 0;
settingMode = true; // 設定モード開始
} else {
unsigned long pressDuration = millis() - lastButtonPress;
if (pressDuration > 1500 && !longPress) {
longPress = true;
toggleTempoChangeRate();
}
}
} else {
if (buttonPressed) {
buttonPressed = false;
settingMode = false; // 設定モード終了
if (!longPress) {
sendTempoInMorse(tempo);
}
longPress = false;
}
}

if (digitalRead(TempoUP_PIN) == LOW) {
delay(50); // デバウンス
if (digitalRead(TempoUP_PIN) == LOW) {
changeTempo(tempoChangeRate);
while (digitalRead(TempoUP_PIN) == LOW) {
delay(200);
changeTempo(tempoChangeRate);
tone(PIEZO_PIN, 800, 30); // ピ音
if (tempo >= 200) {
for (int i = 0; i < 4; i++) {
tone(PIEZO_PIN, 800, 30); // ピピピピ音
delay(100);
}
break;
}
}
EEPROM.write(0, tempo); // EEPROMにテンポを記憶
}
}

if (digitalRead(TempoDWN_PIN) == LOW) {
delay(50); // デバウンス
if (digitalRead(TempoDWN_PIN) == LOW) {
changeTempo(-tempoChangeRate);
while (digitalRead(TempoDWN_PIN) == LOW) {
delay(200);
changeTempo(-tempoChangeRate);
tone(PIEZO_PIN, 800, 30); // ピピ音
if (tempo <= 40) {
for (int i = 0; i < 4; i++) {
tone(PIEZO_PIN, 800, 30); // ピピピピ音
delay(100);
}
break;
}
}
EEPROM.write(0, tempo); // EEPROMにテンポを記憶
}
}

if (!settingMode) {
playMetronome();
}
}

void setTempo(int newTempo) {
tempo = newTempo;
EEPROM.write(0, tempo); // EEPROMにテンポを記憶
tone(PIEZO_PIN, 800, 30); // ピピ音
delay(200); // 音の間隔
}

void changeTempo(int change) {
tempo += change;
if (tempo < 40) tempo = 40;
if (tempo > 200) tempo = 200;
tone(PIEZO_PIN, 800, 30); // ピ音
delay(200); // 音の間隔
}

void playMetronome() {
tone(PIEZO_PIN, 800, 30);
digitalWrite(LED_PIN, HIGH);
delay(30); // LED点灯時間
digitalWrite(LED_PIN, LOW);
delay(60000 / tempo - 30); // テンポに応じた待機時間
}

void sendTempoInMorse(int tempo) {
int hundreds = tempo / 100;
int tens = (tempo / 10) % 10;
int ones = tempo % 10;
sendDigitInMorse(hundreds);
delay(300); // 字と字の間のスペース
sendDigitInMorse(tens);
delay(300); // 字と字の間のスペース
sendDigitInMorse(ones);
}

void sendDigitInMorse(int digit) {
const char* morseDigits[] = {
"-----", ".----", "..---", "...--", "....-", ".....",
"-....", "--...", "---..", "----."
};
const char* morseCode = morseDigits[digit];
while (*morseCode) {
if (*morseCode == '.') {
tone(PIEZO_PIN, 800, 50); // 短点
delay(50);
} else if (*morseCode == '-') {
tone(PIEZO_PIN, 800, 150); // 長点
delay(150);
}
delay(50); // 符号の間のスペース
morseCode++;
}
}

void toggleTempoChangeRate() {
if (tempoChangeRate == 1) {
tempoChangeRate = 5;
tone(PIEZO_PIN, 400, 50); // ポ音
delay(100);
tone(PIEZO_PIN, 800, 50); // ピ音
} else {
tempoChangeRate = 1;
tone(PIEZO_PIN, 800, 50); // ピ音
delay(100);
tone(PIEZO_PIN, 400, 50); // ポ音
}
EEPROM.write(1, tempoChangeRate); // EEPROMにレートを記憶
}