I need help! My project is supposed to receive a Morse code input saying "hello" and output a Morse code output saying "howdy". Everything works well until it starts outputting the word "howdy". It only puts out the Morse code for the letter "h" then stops before it starts reading for a new input. What am I doing wrong here?
int tonePin = 2;
int toneFreq = 1000;
int ledPin = 13;
int buttonPin = 8;
int debounceDelay = 30;
int dotLength = 440; // dotLength = basic unit of speed in milliseconds
int dashLength = dotLength * 3;
int letterSpace = dotLength * 3;
int wordSpace = dotLength * 9;
float wpm = 1200. / dotLength;
int t1, t2, onTime, gap;
bool newLetter, newWord, letterFound, keyboardText;
int lineLength = 0;
int maxLineLength = 20;
char* letters[] = {
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", // A-I
".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", // J-R
"...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." // S-Z
};
char* numbers[] = {
"-----", ".----", "..---", "...--", "....-", //0-4
".....", "-....", "--...", "---..", "----." //5-9
};
String dashSeq = "";
char keyLetter, ch;
int i, index;
String morseInput = ""; // Track the incoming Morse code sequence
unsigned long lastInputTime = 0; // Track last input time for timeout
const unsigned long timeoutDuration = 20000; // 20 seconds timeout for new word
void setup() {
delay(500);
pinMode(ledPin, OUTPUT);
pinMode(tonePin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
Serial.println();
Serial.println("-------------------------------");
Serial.println("Morse Code decoder/encoder");
Serial.print("Speed=");
Serial.print(wpm);
Serial.print("wpm, ");
Serial.print("dot=");
Serial.print(dotLength);
Serial.println("ms");
// Test the LED and tone
tone(tonePin, toneFreq);
digitalWrite(ledPin, HIGH);
delay(2000);
digitalWrite(ledPin, LOW);
noTone(tonePin);
delay(600);
//flash to demonstrate the expected key speed
//A
Serial.print("A .- ");
index = 'A' - 65;
flashSequence(letters[index]);
delay(wordSpace);
//B
Serial.print("B -... ");
index = 'B' - 65;
flashSequence(letters[index]);
delay(wordSpace);
//C
Serial.print("C -.-. ");
index = 'C' - 65;
flashSequence(letters[index]);
delay(wordSpace);
Serial.println();
Serial.println("-------------------------------");
Serial.println("Click field in Serial Monitor,");
Serial.println("type text and press Enter, or");
Serial.println("Key in Morse Code to decode:");
Serial.println("-------------------------------");
newLetter = false; //if false, do NOT check for end of letter gap
newWord = false; //if false, do NOT check for end of word gap
keyboardText = false;
}
void loop() {
// Check if there has been any input for more than 30 seconds
if (millis() - lastInputTime > timeoutDuration) {
morseInput = ""; // Clear morseInput after timeout
Serial.println("\nTimeout! Waiting for new Morse code input...");
}
// Wait for Morse code input
if (digitalRead(buttonPin) == LOW) { // Button pressed (start of Morse input)
newLetter = true;
newWord = true;
t1 = millis(); // Time at button press
digitalWrite(ledPin, HIGH); // Turn on LED and tone
tone(tonePin, toneFreq);
delay(debounceDelay);
while (digitalRead(buttonPin) == LOW) { // Wait for button release
delay(debounceDelay);
}
delay(debounceDelay);
t2 = millis(); // Time at button release
onTime = t2 - t1; // Length of dot or dash keyed in
digitalWrite(ledPin, LOW); // Turn off LED and tone
noTone(tonePin);
// Check if dot or dash
if (onTime <= dotLength * 1.5) {
dashSeq = dashSeq + "."; // Dot
} else {
dashSeq = dashSeq + "-"; // Dash
}
lastInputTime = millis(); // Reset input time
}
// Look for a gap >= letterSpace to signal end of letter
gap = millis() - t2;
if (newLetter == true && gap >= letterSpace) {
// Check through letter sequences to find matching dash sequence
letterFound = false;
keyLetter = 63; // char 63 is "?"
for (i = 0; i <= 25; i++) {
if (dashSeq == letters[i]) {
keyLetter = i + 65;
letterFound = true;
break; // Don't keep checking if letter found
}
}
if (letterFound == false) { // Now check for numbers
for (i = 0; i <= 10; i++) {
if (dashSeq == numbers[i]) {
keyLetter = i + 48;
letterFound = true;
break; // Don't keep checking if number found
}
}
}
Serial.print(keyLetter);
if (letterFound == false) { // Buzz for unknown key sequence
tone(tonePin, 100, 500);
}
// Add the received sequence to morseInput
morseInput += dashSeq + " ";
dashSeq = ""; // Reset dashSeq after each letter
// Check if "HELLO" was received in Morse code
if (morseInput == ".... . .-.. .-.. --- ") {
Serial.println("\nDetected 'HELLO' in Morse code. Flashing 'HOWDY'...");
flashSequence(".... --- .-- -.. -.-- "); // Morse code for "HOWDY"
}
newLetter = false; // Reset
lineLength = lineLength + 1;
}
// Insert line breaks
if (lineLength >= maxLineLength) {
Serial.println();
lineLength = 0;
}
}
void flashSequence(char* sequence) {
int i = 0;
while (sequence[i] == '.' || sequence[i] == '-') {
flashDotOrDash(sequence[i]);
i++;
}
}
void flashDotOrDash(char dotOrDash) {
digitalWrite(ledPin, HIGH);
tone(tonePin, toneFreq);
if (dotOrDash == '.') {
delay(dotLength);
} else {
delay(dashLength);
}
digitalWrite(ledPin, LOW);
noTone(tonePin);
delay(dotLength); // Small gap between flashes
}
