#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '0', '*', '+'},
{' ', ' ', '/', '-'},
{' ', ' ', '<', '('},
{' ', 'C', '=', ')'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String equation = "";
String currentBinary = "";
bool error = false;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.println(key);
if (key == '0' || key == '1') {
currentBinary += key;
equation += key;
updateLCD();
} else if (key == '+' || key == '-' || key == '*' || key == '/' || key == '(' || key == ')') {
if (currentBinary.length()) {
equation = replaceLastBinaryWithDecimal(equation, currentBinary);
currentBinary = "";
}
equation += key;
updateLCD();
} else if (key == '=') {
if (currentBinary.length()) {
equation = replaceLastBinaryWithDecimal(equation, currentBinary);
currentBinary = "";
updateLCD();
}
delay(1000);
calculateEquation();
} else if (key == '<') {
if (currentBinary.length()) {
currentBinary.remove(currentBinary.length() - 1);
equation.remove(equation.length() - 1);
} else if (equation.length()) {
equation.remove(equation.length() - 1);
}
updateLCD();
} else if (key == 'C') {
resetCalculator();
}
}
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(equation);
}
String replaceLastBinaryWithDecimal(String eq, String binary) {
int decimal = binaryToDecimal(binary);
eq.remove(eq.length() - binary.length());
eq += String(decimal);
return eq;
}
void calculateEquation() {
lcd.clear();
if (hasInvalidInput(equation)) {
lcd.setCursor(0, 0);
lcd.print("Invalid Input!");
delay(2000);
resetCalculator();
return;
}
int result = evaluateExpression(equation);
lcd.setCursor(0, 0);
lcd.print("Result:");
lcd.setCursor(0, 1);
lcd.print(result);
}
bool hasInvalidInput(String eq) {
if (eq.length() == 0) return true;
if (eq.indexOf("++") != -1 || eq.indexOf("--") != -1 || eq.indexOf("**") != -1 || eq.indexOf("//") != -1) return true;
if (eq[0] == '+' || eq[0] == '-' || eq[0] == '*' || eq[0] == '/') return true;
if (eq[eq.length() - 1] == '+' || eq[eq.length() - 1] == '-' || eq[eq.length() - 1] == '*' || eq[eq.length() - 1] == '/') return true;
int openParentheses = 0;
for (int i = 0; i < eq.length(); i++) {
if (eq[i] == '(') {
openParentheses++;
} else if (eq[i] == ')') {
openParentheses--;
if (openParentheses < 0) return true;
}
}
if (openParentheses != 0) return true;
return false;
}
int evaluateExpression(String eq) {
int index = 0;
return parseExpression(eq, index);
}
int parseExpression(String &eq, int &index) {
int result = parseTerm(eq, index);
while (index < eq.length() && (eq[index] == '+' || eq[index] == '-')) {
char op = eq[index++];
int term = parseTerm(eq, index);
if (op == '+') {
result += term;
} else if (op == '-') {
result -= term;
}
}
return result;
}
int parseTerm(String &eq, int &index) {
int result = parseFactor(eq, index);
while (index < eq.length() && (eq[index] == '*' || eq[index] == '/')) {
char op = eq[index++];
int factor = parseFactor(eq, index);
if (op == '*') {
result *= factor;
} else if (op == '/') {
result /= factor;
}
}
return result;
}
int parseFactor(String &eq, int &index) {
if (eq[index] == '(') {
index++;
int result = parseExpression(eq, index);
index++;
return result;
}
int start = index;
while (index < eq.length() && isDigit(eq[index])) {
index++;
}
return eq.substring(start, index).toInt();
}
int binaryToDecimal(String binary) {
int decimal = 0;
for (int i = 0; i < binary.length(); i++) {
decimal = (decimal << 1) | (binary[i] - '0');
}
return decimal;
}
bool isDigit(char c) {
return c >= '0' && c <= '9';
}
void resetCalculator() {
equation = "";
currentBinary = "";
error = false;
lcd.clear();
}