// https://upload.wikimedia.org/wikipedia/commons/b/b5/International_Morse_Code.svg

char message[] = {"Hello, World!"}; // punctuation is ignored
byte oneElement = 100; //  element time in microseconds
int ditPin = 8; // DIO pin 8 (wht LED)
int dahPin = 9; // DIO pin 9 (red LED)

/*
  - Morse timing...
  - One element for DIT/DOT
  - One element for intra-element spacing
  - Three elements for DAH/DASH
  - Three elements for intra-character spacing
  - Seven elements for intra-word spacing
  - Punctuation is ignored
*/

void setup() {
  Serial.begin(115200);
  pinMode(ditPin, OUTPUT);
  pinMode(dahPin, OUTPUT);
  delay(1000); // delay visual start

  for (int i = 0; i < strlen(message); i++) {
    Serial.print(message[i]); // print character in Serial Monitor
    xlat(message[i]); // translate char into morse
  }
}

void loop() {} // to repeat send, move xlat() into loop()

void dit() { // "dot" element
  blink(1, ditPin);
}

void dah() { // "dash" element
  blink (3, dahPin);
}

void blink(byte elements, int led) { // blink the LED
  digitalWrite(led, HIGH);
  delay(elements * oneElement);
  digitalWrite(led, LOW);
  delay(oneElement);
}

void ieg() {
  delay(1 * oneElement); // intra-element gap - built-in to each element
}
void icg() {
  delay(3 * oneElement); // intra-character gap - place between characters
}
void iwg() {
  delay(7 * oneElement); // intra-word gap - place between words
}

void xlat(char i) {
  switch (i) { // UPPER CASE default to lower case letters
    case 'A': case 'a': dit(); dah(); break;
    case 'B': case 'b': dah(); dit(); dit(); dit(); break;
    case 'C': case 'c': dah(); dit(); break;
    case 'D': case 'd': dah(); dit(); dit(); break;
    case 'E': case 'e': dit(); break;
    case 'F': case 'f': dit(); dit(); dah(); dit(); break;
    case 'G': case 'g': dah(); dah(); dit(); break;
    case 'H': case 'h': dit(); dit(); dit(); dit(); break;
    case 'I': case 'i': dit(); dit(); break;
    case 'J': case 'j': dit(); dah(); dah(); dah(); break;
    case 'K': case 'k': dah(); dit(); dah(); break;
    case 'L': case 'l': dit(); dah(); dit(); dit(); break;
    case 'M': case 'm': dah(); dah(); break;
    case 'N': case 'n': dah(); dit(); break;
    case 'O': case 'o': dah(); dah(); dah(); break;
    case 'P': case 'p': dit(); dah(); dah(); dit(); break;
    case 'Q': case 'q': dah(); dah(); dit(); dah(); break;
    case 'R': case 'r': dit(); dah(); dit(); break;
    case 'S': case 's': dit(); dit(); dit(); break;
    case 'T': case 't': dah(); break;
    case 'U': case 'u': dit(); dit(); dah(); break;
    case 'V': case 'v': dit(); dit(); dit(); dah(); break;
    case 'W': case 'w': dit(); dah(); dah(); break;
    case 'X': case 'x': dah(); dit(); dit(); dah(); break;
    case 'Y': case 'y': dah(); dit(); dah(); dah(); break;
    case 'Z': case 'z': dah(); dah(); dit(); dit(); break;
    case ' ': iwg(); break; // intra-word gap (space)
    case '0': dah(); dah(); dah(); dah(); dah(); break;
    case '1': dit(); dah(); dah(); dah(); dah(); break;
    case '2': dit(); dit(); dah(); dah(); dah(); break;
    case '3': dit(); dit(); dit(); dah(); dah(); break;
    case '4': dit(); dit(); dit(); dit(); dah(); break;
    case '5': dit(); dit(); dit(); dit(); dit(); break;
    case '6': dah(); dit(); dit(); dit(); dit(); break;
    case '7': dah(); dah(); dit(); dit(); dit(); break;
    case '8': dah(); dah(); dah(); dit(); dit(); break;
    case '9': dah(); dah(); dah(); dah(); dit(); break;
    default: break; // no punctuation
  }
  icg(); // intra-character gap
}
DAH
DIT