#include <LiquidCrystal_I2C.h>
#include "Keypad.h"
#define ROWS 4
#define COLS 4
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
const String alpha = "!@_$%?1 ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7 TUV8 WXYZ9 0 ";
const byte rowPins[ROWS] = {9, 8, 7, 6};
const byte colPins[COLS] = {5, 4, 3, 2};
int x = 0, y = 0, minValue = 0, maxValue = 0, keyPressTime = 100;
String msg = "";
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
lcd.begin(16, 2);
lcd.clear();
lcd.setBacklight(HIGH);
}
void loop() {
enterMSG();
}
void parseKey(int minValue, int maxValue, char keyPress, String& msg, int& x, int& y, int keyPressTime, String removeDirection = "", int numLines = 1) {
int ch = minValue;
char key = keyPress;
if (removeDirection == "up") {
for (int i = 0; i < numLines; i++) {
int lastLineIndex = msg.lastIndexOf('\n', msg.length() - 2);
if (lastLineIndex < 0) {
msg = "";
x = 0;
y = 0;
lcd.clear();
lcd.setCursor(x,y);
} else {
msg = msg.substring(0, lastLineIndex + 1);
y--;
if (y < 0) {
y = 1;
}
x = msg.lastIndexOf('\n', lastLineIndex - 1);
if (x < 0) {
x = 0;
} else {
x = lastLineIndex - x;
}
lcd.setCursor(x, y);
if (i == numLines - 1 && msg.indexOf('\n', lastLineIndex + 1) < 0) {
msg = msg.substring(0, lastLineIndex + 1);
lcd.setCursor(0, y);
lcd.print("");
lcd.setCursor(0, y);
x = 0;
y--;
if (y < 0) {
y = 1;
}
}
}
}
} else if (removeDirection == "down") {
for (int i = 0; i < numLines; i++) {
int nextLineIndex = msg.indexOf('\n', msg.length() - 1);
if (nextLineIndex < 0) {
msg = "";
x = 0;
y = 0;
lcd.clear();
lcd.setCursor(x,y);
} else {
msg = msg.substring(0, nextLineIndex + 1);
x = 0;
y++;
if (y > 1) {
y = 0;
}
lcd.setCursor(x, y);
}
}
} else if (keyPress == 'A') {
if ((x > 0) || (y > 0)) {
x--;
lcd.setCursor(x,y);
lcd.print(" ");
msg.remove(msg.length() - 1);
}
} else {
for (int i = 0; i < keyPressTime; i++) {
if (key == keyPress) {
lcd.setCursor(x, y);
lcd.print(alpha[ch]);
ch++;
if (ch > maxValue) {
ch = minValue;
i = 0;
}
}
key = customKeypad.getKey();
delay(15);
}
x++;
msg += alpha[ch - 1];
if (x > 15) {
y = 1;
x = 0;
}
}
}
void enterMSG() {
char key;
lcd.clear();
x = 0;
y = 0;
msg = "";
while (true) {
key = customKeypad.waitForKey();
if (key == '#') break;
int rangeStart, rangeEnd;
switch(key) {
case '1': rangeStart = 0; rangeEnd = 7; break;
case '2': rangeStart = 8; rangeEnd = 12; break;
case '3': rangeStart = 13; rangeEnd = 17; break;
case '4': rangeStart = 18; rangeEnd = 22; break;
case '5': rangeStart = 23; rangeEnd = 27; break;
case '6': rangeStart = 28; rangeEnd = 32; break;
case '7': rangeStart = 33; rangeEnd = 38; break;
case '8': rangeStart = 39; rangeEnd = 43; break;
case '9': rangeStart = 44; rangeEnd = 49; break;
case '0': rangeStart = 50; rangeEnd = 53; break;
case 'A': rangeStart = 54; rangeEnd = 55; break;
default: continue;
}
parseKey(rangeStart, rangeEnd, key, msg, x, y, keyPressTime);
}
}