// sketch 04_05_morse_flasher
// Aquest sketch converteix caràcters llegits per Serial en codi Morse, fent parpellejar un LED.

// Definició del pin del LED i del temps base per un punt (dot)
const int ledPin = 13;        // Utilitza el pin digital 13 per controlar el LED
const int dotDelay = 200;       // Durada d'un punt en mil·lisegons (200 ms)

// Array de cadenes que contenen els codis Morse per a les lletres A-Z
char* letters[] = {
  ".-",    // A: Codi Morse per A
  "-...",  // B: Codi Morse per B
  "-.-.",  // C: Codi Morse per C
  "-..",   // D: Codi Morse per D
  ".",     // E: Codi Morse per E
  "..-.", // F: Codi Morse per F
  "--.",   // G: Codi Morse per G
  " ...", // H: Codi Morse per H (nota: aquest element conté un espai extra, pot ser un error tipogràfic)
  "..",    // I: Codi Morse per I
  // A-I
  ".---", // J: Codi Morse per J
  "-.-",  // K: Codi Morse per K
  ".-..", // L: Codi Morse per L
  "--",   // M: Codi Morse per M
  "-.",   // N: Codi Morse per N
  "---",  // O: Codi Morse per O
  ".--.", // P: Codi Morse per P
  "--.-", // Q: Codi Morse per Q
  ".-.",  // R: Codi Morse per R
  // J-R
  "...",  // S: Codi Morse per S
  "-",    // T: Codi Morse per T
  "..-",  // U: Codi Morse per U
  "...-", // V: Codi Morse per V
  ".--",  // W: Codi Morse per W
  "-..-", // X: Codi Morse per X
  "-.--", // Y: Codi Morse per Y
  "--.."  // Z: Codi Morse per Z
  // S-Z
};

// Array de cadenes amb els codis Morse per als números 0-9
char* numbers[] = {
  "-----", // 0: Codi Morse per 0
  ".----", // 1: Codi Morse per 1
  "..---", // 2: Codi Morse per 2
  "...--", // 3: Codi Morse per 3
  "....-", // 4: Codi Morse per 4
  ".....", // 5: Codi Morse per 5
  "-....", // 6: Codi Morse per 6
  "--...", // 7: Codi Morse per 7
  "---..", // 8: Codi Morse per 8
  "----."  // 9: Codi Morse per 9
};

// La funció setup() s'executa una vegada al principi
void setup() {
  pinMode(ledPin, OUTPUT);    // Configura el pin del LED com a sortida
  Serial.begin(9600);         // Inicia la comunicació sèrie a 9600 baud
}

// La funció loop() s'executa de manera repetitiva
void loop() {
  char ch;  // Variable per emmagatzemar el caràcter llegit
  if (Serial.available() > 0) {      // Comprova si hi ha dades disponibles al port sèrie
    ch = Serial.read();              // Llegeix un caràcter des del port sèrie
    if (ch >= 'a' && ch <= 'z') {
      flashSequence(letters[ch - 'a']);  // Si és lletra minúscula, converteix el caràcter en l'índex corresponent per a letters
    }
    else if (ch >= 'A' && ch <= 'Z') {
      flashSequence(letters[ch - 'A']);  // Si és lletra majúscula, converteix el caràcter en l'índex corresponent per a letters
    }
    else if (ch >= '0' && ch <= '9') {
      flashSequence(numbers[ch - '0']);  // Si és número, converteix el caràcter en l'índex corresponent per a numbers
    }
    else if (ch == ' ') {
      delay(dotDelay * 4);  // Si es detecta un espai, espera més temps per separar paraules
    }
  }
}

// Funció que rep una cadena (seqüència Morse) i la processa símbol a símbol
void flashSequence(char* sequence) {
  int i = 0;  // Inicialitza l'índex
  while (sequence[i] != '\0') {  // Itera mentre no s'arribi al caràcter null que indica el final de la cadena
    flashDotOrDash(sequence[i]); // Crida la funció per processar el símbol (punt o guió)
    i++;                         // Passa al següent símbol
  }
}

// Funció que fa parpellejar el LED segons si el símbol és punt o guió
void flashDotOrDash(char dotOrDash) {
  digitalWrite(ledPin, HIGH);  // Engega el LED
  if (dotOrDash == '.') {
    delay(dotDelay);           // Si és punt, espera la durada base (dotDelay)
  }
  else {
    // Ha de ser un guió
    delay(dotDelay * 3);       // Si és guió, espera tres vegades la durada base
  }
  digitalWrite(ledPin, LOW);   // Apaga el LED
  delay(dotDelay);             // Espera un temps curt entre símbols
}

// Aquest sketch inclou una funció loop() que es crida automàticament i repetidament.