Hi, I am trying to build a Morse Code translator at home that will print to an LCD screen the English translation of the Morse Code imputed through a pushbutton. The code I developed functions okay, but I have a few unexpected bugs. First, if there is a long duration between button inputs while the attached program is running, the LCD will appear to move the cursor down one row, despite there being nothing in the code intended to move the cursor outside of setup. Second, the program will print nothing to the LCD unless a character is printed to the LCD during setup. This issue does not occur when printing to the serial monitor. I am not sure why these issues are occuring and would like help resolving them. Thanks for your time, Eli.
The hardware I am using is a Chinese Arduino clone (the Elegoo Uno R3), a LCD1602 Module Hitachi-compatible LCD display (Sorry I can't get more specific, no information other than that was included in the starter kit I am using), and two-pin pushbutton.
Schematic is attached below
Code is included below
// true if the button was down when we last checked
boolean last_button_state = false;
// include the library code:
int count = 0;
unsigned long starttime = 0;
unsigned long endtime = 0;
float totaltime = 0;
const int dot = 1000;
const int dash = 3000;
const int lspace = dot * 2;
const int wspace = dot * 6;
const float tolerance = 0.2;
String letter = "";
//Keeping track of sequence of dots and dashes is being typed
const String morse_code_table[26] = {
/* A */ ".-",
/* B */ "-...",
/* C */ "-.-.",
/* D */ "-..",
/* E */ ".",
/* F */ "..-.",
/* G */ "--.",
/* H */ "....",
/* I */ "..",
/* J */ ".---",
/* K */ "-.-",
/* L */ ".-..",
/* M */ "--",
/* N */ "-.",
/* O */ "---",
/* P */ ".--.",
/* Q */ "--.-",
/* R */ ".-.",
/* S */ "...",
/* T */ "-",
/* U */ "..-",
/* V */ "...-",
/* W */ ".--",
/* X */ "-..-",
/* Y */ "-.--",
/* Z */ "--..",
};
#include <LiquidCrystal.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// set up the LCD's number of columns and rows:
const int kButtonPin = 10;
// Pin that is being connected to the button for Morse imput.
char lettercheck(String letter) {
for (int i = 0; i < 26; ++i) {
if (letter == morse_code_table[i]) {
return 'A' + i;
}
}
}
void setup() {
// put your setup code here, to run once:
pinMode(kButtonPin, INPUT_PULLUP);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(15, 0);
//I'm not sure why the lcdprint needs to be there, but without it nothing prints when the button is pressed.
lcd.print(" ");
lcd.autoscroll();
}
void loop() {
bool new_button_state = (digitalRead(kButtonPin) == LOW);
unsigned long now = millis();
if ((last_button_state == false) && (new_button_state == true)) {
// The button was not pressed the last time I iterated through this loop and it is now pressed.
if ((now > (endtime + (lspace - (lspace * tolerance)))) && (now < (endtime + (wspace - (wspace * tolerance)))) && (endtime != 0)) {
// If the current time is greater than the last time the button was pressed, plus the length of the space between letters
// minus the space between letters times the tolerance variable, and less than the last time the button was pressed, plus the length of the space between words
// minus the space between words times the tolerance variable and the button has been pressed more than once
lcd.print(lettercheck(letter));
// Compare the sequence of dashes and dots appended to letter with the morse code table, and print the result
Serial.print(lettercheck(letter));
// Print the result to the serial monitor for testing
letter = "";
// Reset the letter string keeping track of the dash-dot sequence
count = 0;
} else if ((now > (endtime + (wspace - (wspace * tolerance)))) && (endtime != 0)) {
// If the current time is greater than the last time the button was pressed, plus the length of the space between words
// minus the space between words times the tolerance variable and the button has been pressed more than once
lcd.print(lettercheck(letter));
Serial.print(lettercheck(letter));
lcd.print(" ");
Serial.print(" ");
letter = "";
count = 0;
}
last_button_state = true;
starttime = now;
} else if ((last_button_state == true) && (new_button_state == false)) {
// The button was just released.
last_button_state = false;
endtime = now;
totaltime = (endtime - starttime);
if (totaltime <= (dot)) {
//lcd.print("DOT");
//lcd.println(count);
letter += ".";
count += 1;
if (count >= 5) {
count = 0;
//lcd.print(letter);
lcd.print(lettercheck(letter));
Serial.print(lettercheck(letter));
letter = "";
}
} else {
//lcd.println("Dash");
//lcd.println(count);
letter += "-";
count += 1;
if (count >= 5) {
count = 0;
//lcd.print(letter);
lcd.print(lettercheck(letter));
Serial.print(lettercheck(letter));
letter = "";
}
}
}
delay(15);
}```

