Why does my 16x2 LCD displays weird letters and can't insert key from keypad? I'm a newbie on Arduino here, and this is my first project on 16x2 LCD, 4x4 keypad and others. So, the story is, after I uploaded the program for my group's Arduino alarm clock to the Arduino board, the LCD displays black boxes on the first row of the LCD. But after soldering the LCD pins again and connect the Vo to the 10k ohm potentiometer, the LCD can display the "welcome" part properly. This can be seen in the two pictures below.



However, after a while, there are weird letters appearing on the second row of the LCD, blinking from the first picture below to the second picture again and again. Plus, I couldn't input any key from the keypad to the LCD, since the display's stuck at there.



I'm not sure if there's any problem in the circuit or in the programming. I'm quite confused here. Below is the code I uploaded to the Arduino board. Thank you in advance.


#include &lt;EEPROM.h&gt;
#include &lt;Keypad.h&gt;
#include &lt;DS1307.h&gt;
#include &lt;Wire.h&gt;
#include &lt;Adafruit_GFX.h&gt;
#include &lt;LiquidCrystal.h&gt;

DS1307 rtc(SDA, SCL);
LiquidCrystal lcd(A3, A2, A1, A0, 5, 4);
Time t;

#define buz 3

int Hor, Min, Sec, h, m, s;
int ASCII = 48;
char* tim;
char* dat;
const char key = 0;
char buffer[2];
const byte numRows= 4;
const byte numCols= 4;
char keymap[numRows][numCols]=
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[numRows] = {12, 11, 10, 9};
byte colPins[numCols]= {8, 7, 6, 5};
Keypad myKeypad= Keypad(makeKeymap(keymap),rowPins, colPins, numRows, numCols);

void setup() {
  Wire.begin();
  rtc.begin();
  pinMode(buz, OUTPUT);
  lcd.begin(16, 2);
  welcome();

  rtc.setDOW(SATURDAY); //Set Day-of-Week to SUNDAY
  rtc.setTime(10, 54, 0); //Set the time to 12:00:00     (24hr format)
  rtc.setDate(7, 1, 2017); //Day, Month, Year
}

void loop() {
  t = rtc.getTime();
  Hor = t.hour;
  Min = t.min;
  Sec = t.sec;
  tim = rtc.getTimeStr();
  dat = rtc.getDateStr();
  char key = myKeypad.getKey();

  if (key == 'C'){
    digitalWrite(buz, LOW);
    EEPROM.write(2, ASCII+6);
    EEPROM.write(3, ASCII);
  }

  if(key == '#'){
    lcd.setCursor(0,0);
    lcd.print("Enter New Time");
    lcd.setCursor(0,1);
    int j =0;
    int i=0;
    while( j&lt;6)
    {
      if(i==2 || i == 5){
        lcd.print(":");
        lcd.display();
        i++;
      }
      key=myKeypad.getKey();
      if(key)
      {
        lcd.print(key);
        lcd.display();
        EEPROM.write(j,key);
        j++;
        i++;
      }
    }
  }

  changealarm();
  checkalarm();
  timedate();
}

void checkalarm(){
  if( Hor == h &amp;&amp; Min == m)
  {
    delay(3000);
    lcd.setCursor(0,1);
    lcd.print("Hold C");
    digitalWrite(buz, HIGH);
    delay(3000);
  }
}

void changealarm(){
  buffer[0]=EEPROM.read(0);
  buffer[1]=EEPROM.read(1);
  h = atoi(buffer);
  buffer[0]=EEPROM.read(2);
  buffer[1]=EEPROM.read(3);
  m = atoi(buffer);
  buffer[0]=EEPROM.read(4);
  buffer[1]=EEPROM.read(5);
  s = atoi(buffer);
}

void timedate(){
  lcd.setCursor(0,0);
  lcd.print("Time: ");
  lcd.print(rtc.getTimeStr());

  lcd.setCursor(0,1);
  lcd.print("Date: ");
  lcd.print(rtc.getDateStr());
  delay(3000);
  lcd.setCursor(0,1);
  lcd.print("Alarm: ");
  lcd.print(h);
  lcd.print(".");
  lcd.print(m);
  lcd.print(".");
  lcd.print(s);
  delay(3000);
}

void welcome(){
  lcd.setCursor(0,0);
  lcd.print("Welcome");

  lcd.setCursor(0,1);
  lcd.print("To");
  delay(3000);

  lcd.setCursor(0,1);
  lcd.print("TIMeProject");
  delay(3000);
}
In your changealarm() function, you call atoi(buffer), and buffer is defined as char buffer[2].

atoi() expects a c-style string, which is null-terminated, and you have to include space for the null termination character ('\0', 0, 0x00, etc.), but you write to both allocated spaces in the changealarm() function. If your 2nd byte of each EEPROM space (1, 3, 5) is non-zero, then your have an unterminated string. 

atoi() expects a null-terminated string, and so the behavior is unexpected. Probably atoi() is running into other memory. If the string being sent is not representable by a int type, then the behavior of atoi() is undefined.



A quick fix would be to increase the size of buffer and guarantee null termination:

char buffer[3];  // Make the buffer 3 bytes long
[...]
void changealarm() {
  buffer[2]=0;   // Set the 3rd byte to zero to null-terminate

  buffer[0]=EEPROM.read(0);
  buffer[1]=EEPROM.read(1);
  h = atoi(buffer);
  buffer[0]=EEPROM.read(2);
  buffer[1]=EEPROM.read(3);
  m = atoi(buffer);
  buffer[0]=EEPROM.read(4);
  buffer[1]=EEPROM.read(5);
  s = atoi(buffer);
}