#include <Keypad.h>
#include <LiquidCrystal.h>
#include <math.h>
// ================= LCD Configuration =================
LiquidCrystal lcd(16, 17, 18, 19, 21, 22); // RS, EN, D4, D5, D6, D7
// ================= Keypad Configuration =================
const byte ROWS = 4;
const byte COLS = 4;
byte rowPins[ROWS] = {32, 33, 25, 26}; // Connect to keypad rows
byte colPins[COLS] = {14, 12, 13, 4}; // Connect to keypad columns
// ================= Keypad Layout =================
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// ================= Mode Configuration =================
enum Mode { STANDARD, SCIENTIFIC, UNIT_CONVERTER, CURRENCY_CONVERTER, GAME };
Mode selectedMode = STANDARD;
bool inMode = false; // Flag to track if user has entered a mode
String calcInput = "";
float calcResult = 0;
// Game Variables
String gameInput = "";
int gameNum1 = 0;
int gameNum2 = 0;
int gameCorrectAnswer = 0;
void setup() {
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Select Mode:");
lcd.setCursor(0, 1);
lcd.print("1:Std 2:Sci 3:Unit");
delay(1500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("4:Curr 5:Game");
delay(1500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press D to enter");
randomSeed(analogRead(0)); // Initialize random seed for the game mode
}
void loop() {
char key = keypad.getKey();
if (key) {
if (!inMode) {
// Mode selection phase
if (key >= '1' && key <= '5') {
if (key == '1') {
selectedMode = STANDARD;
} else if (key == '2') {
selectedMode = SCIENTIFIC;
} else if (key == '3') {
selectedMode = UNIT_CONVERTER;
} else if (key == '4') {
selectedMode = CURRENCY_CONVERTER;
} else if (key == '5') {
selectedMode = GAME;
}
displaySelectedMode();
} else if (key == 'D') { // Enter the selected mode
inMode = true;
enterMode(selectedMode);
}
} else {
// Inside the selected mode: handle user input
processModeInput(key);
}
}
}
void displaySelectedMode() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mode Selected:");
lcd.setCursor(0, 1);
switch (selectedMode) {
case STANDARD:
lcd.print("Std Calc");
break;
case SCIENTIFIC:
lcd.print("Sci Calc");
break;
case UNIT_CONVERTER:
lcd.print("Unit Conv");
break;
case CURRENCY_CONVERTER:
lcd.print("Curr Conv");
break;
case GAME:
lcd.print("Game");
break;
}
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press D to enter");
delay(1000);
lcd.clear();
}
void enterMode(Mode mode) {
lcd.clear();
lcd.setCursor(0, 0);
switch (mode) {
case STANDARD:
lcd.print("Std Calc >");
calcInput = "";
break;
case SCIENTIFIC:
lcd.print("Sci Calc >");
calcInput = "";
break;
case UNIT_CONVERTER:
lcd.print("Unit Conv >");
break;
case CURRENCY_CONVERTER:
lcd.print("Curr Conv >");
break;
case GAME:
lcd.print("Game >");
startGameProblem();
break;
}
delay(1000);
lcd.clear();
}
void processModeInput(char key) {
switch (selectedMode) {
case STANDARD:
processStandardCalc(key);
break;
case SCIENTIFIC:
processScientificCalc(key);
break;
case UNIT_CONVERTER:
processUnitConverter(key);
break;
case CURRENCY_CONVERTER:
processCurrencyConverter(key);
break;
case GAME:
processGameInput(key);
break;
}
}
void processStandardCalc(char key) {
lcd.setCursor(0, 1);
if (key == '*') {
calcInput = "";
lcd.print("Cleared ");
} else if (key == '#') {
int plusIndex = calcInput.indexOf('+');
if (plusIndex != -1) {
String part1 = calcInput.substring(0, plusIndex);
String part2 = calcInput.substring(plusIndex + 1);
float a = part1.toFloat();
float b = part2.toFloat();
calcResult = a + b;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Result:");
lcd.setCursor(0, 1);
lcd.print(calcResult);
delay(2000);
lcd.clear();
lcd.print("Std Calc >");
calcInput = "";
} else {
lcd.print("Invalid Expr");
delay(1500);
lcd.clear();
lcd.print("Std Calc >");
calcInput = "";
}
} else if (key == 'A') { // Addition operation
calcInput += '+';
lcd.print(calcInput);
} else {
calcInput += key;
lcd.print(calcInput);
}
}
void processScientificCalc(char key) {
lcd.setCursor(0, 1);
if (key >= '0' && key <= '9') {
calcInput += key;
lcd.print(calcInput);
} else if (key == 'A') { // Square root operation
float a = calcInput.toFloat();
float result = sqrt(a);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("sqrt(");
lcd.print(a);
lcd.print(")=");
lcd.setCursor(0, 1);
lcd.print(result);
delay(2500);
lcd.clear();
lcd.print("Sci Calc >");
calcInput = "";
} else if (key == 'B') { // Exponentiation operation
calcInput += '^';
lcd.print(calcInput);
} else if (key == 'C') { // Clear the input
calcInput = "";
lcd.clear();
lcd.print("Sci Calc >");
} else if (key == '#') {
int caretIndex = calcInput.indexOf('^');
if (caretIndex != -1) {
String baseStr = calcInput.substring(0, caretIndex);
String expStr = calcInput.substring(caretIndex + 1);
float baseVal = baseStr.toFloat();
float expVal = expStr.toFloat();
float result = pow(baseVal, expVal);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("pow(");
lcd.print(baseVal);
lcd.print(",");
lcd.print(expVal);
lcd.print(")=");
lcd.setCursor(0, 1);
lcd.print(result);
delay(2500);
lcd.clear();
lcd.print("Sci Calc >");
calcInput = "";
} else {
lcd.clear();
lcd.print("Invalid Expr");
delay(1500);
lcd.clear();
lcd.print("Sci Calc >");
calcInput = "";
}
}
}
void processUnitConverter(char key) {
lcd.setCursor(0, 1);
if (key == '*') {
calcInput = "";
lcd.print("Cleared ");
} else if (key == '#') {
float meters = calcInput.toFloat();
float centimeters = meters * 100;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cm: ");
lcd.print(centimeters);
delay(2000);
lcd.clear();
lcd.print("Unit Conv >");
calcInput = "";
} else {
calcInput += key;
lcd.print(calcInput);
}
}
void processCurrencyConverter(char key) {
lcd.setCursor(0, 1);
if (key == '*') {
calcInput = "";
lcd.print("Cleared ");
} else if (key == '#') {
float usd = calcInput.toFloat();
float egp = usd * 30.9; // Exchange rate
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("EGP: ");
lcd.print(egp);
delay(2000);
lcd.clear();
lcd.print("Curr Conv >");
calcInput = "";
} else {
calcInput += key;
lcd.print(calcInput);
}
}
void startGameProblem() {
gameNum1 = random(1, 21);
gameNum2 = random(1, 21);
gameCorrectAnswer = gameNum1 + gameNum2;
gameInput = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(gameNum1);
lcd.print(" + ");
lcd.print(gameNum2);
lcd.print(" = ?");
}
void processGameInput(char key) {
if (key == '*') {
gameInput = "";
lcd.setCursor(0, 1);
lcd.print("Cleared ");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(gameNum1);
lcd.print(" + ");
lcd.print(gameNum2);
lcd.print(" = ?");
} else if (key == '#') {
int userAnswer = gameInput.toInt();
lcd.clear();
if (userAnswer == gameCorrectAnswer) {
lcd.print("Correct!");
} else {
lcd.print("Wrong! Ans:");
lcd.print(gameCorrectAnswer);
}
delay(2000);
startGameProblem();
} else {
gameInput += key;
lcd.setCursor(0, 1);
lcd.print("Ans: ");
lcd.print(gameInput);
}
}