ESP32 Bench
Boards: ESP32, S2, S3, C3, C6
Flash and monitor: Web Serial
← All projects

Morse code decoder

Tap Morse on the BOOT button and watch it turn into letters. It learns your speed as you go, and a buzzer adds a sidetone if you have one.

Starter10 min115200 baud
Board
Fig. 1. Pins this project uses on the ESP32-DevKitC V4, 38 pin. USB connector at the bottom.

Wiring

FromTo boardNote
BOOT buttonGPIO 0Already on the board. It is the Morse key
Buzzer +GPIO 25Optional sidetone. A passive buzzer or piezo
Buzzer -GND

Tested on this board

Not run on this board yet. Treat the wiring and code as a first draft.

Firmware, Arduino sketch for ESP32 Dev Module

// Morse code decoder. The BOOT button is the key: short press = dot, long press = dash.
const int KEY = 0;      // the BOOT button
const int BUZZER = 25;  // optional sidetone, leave unconnected if you have no buzzer
const int TONE_HZ = 650;

const char* LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const char* CODES[] = {
  ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
  "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
  "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",
};

float unit = 120;      // length of one dot in ms; adapts to your speed
String symbol;         // dots and dashes of the letter being keyed
bool keyDown = false;
bool inWord = false;
unsigned long changedAt = 0;

char decode(const String& s) {
  for (int i = 0; i < 36; i++) {
    if (s == CODES[i]) return LETTERS[i];
  }
  return '?';
}

void setup() {
  Serial.begin(115200);
  delay(500);
  pinMode(KEY, INPUT_PULLUP);
  Serial.println("Morse decoder. Key with the BOOT button: short press = dot, long press = dash.");
}

void loop() {
  bool down = digitalRead(KEY) == LOW;
  unsigned long now = millis();
  unsigned long held = now - changedAt;

  if (down != keyDown && held > 15) {  // 15 ms debounce
    if (keyDown) {
      // Key released: was it a dot or a dash?
      noTone(BUZZER);
      if (held < 2 * unit) {
        symbol += '.';
        unit = (unit * 3 + held) / 4;
      } else {
        symbol += '-';
        unit = (unit * 3 + held / 3.0f) / 4;
      }
      unit = constrain(unit, 40.0f, 400.0f);
    } else {
      tone(BUZZER, TONE_HZ);
    }
    keyDown = down;
    changedAt = now;
    return;
  }

  if (!keyDown) {
    if (symbol.length() > 0 && held > 3 * unit) {
      Serial.print(decode(symbol));  // gap between letters
      symbol = "";
      inWord = true;
    } else if (inWord && held > 7 * unit) {
      Serial.printf("  wpm=%d\n", (int)(1200 / unit));  // gap between words
      inWord = false;
    }
  }
  delay(2);
}

Parts

QuantityPartWhere to buy
1×ESP32 dev boardBuy at Amazon
1×Optional passive buzzer or piezoBuy at Adafruit

Amazon buy links may include an Associates tag, and this site may earn a commission from qualifying Amazon purchases at no extra cost to you. Adafruit links are direct.

Libraries

None beyond the ESP32 Arduino core.

Load it

  1. In the Arduino IDE, install the esp32 board package and pick the board named above the sketch.
  2. Paste the sketch, choose the board's port and upload. Hold BOOT if the upload stalls at Connecting.
  3. Close the IDE's serial monitor, then open the bench here to watch the output.

Field notes

  • Start slowly and evenly. The decoder takes a dash as anything longer than two dots, and adjusts the dot length after every symbol.
  • A gap of three dots ends a letter and seven dots ends a word, as in real Morse. Speed is printed as words per minute at the end of each word.
  • Do not hold BOOT while the board resets, or it enters download mode.
  • Try SOS (... --- ...), then your name. A real Morse key or any push button wired from the BOOT pin to GND works too.

Not tested yet

  • Not tested on hardware yet. Compiles for every board listed with Arduino-ESP32 core 3.3.12.

Built it? Send a build report with your board and what the serial port printed. Working reports become the "Tested on this board" entries above.