/*
  Arduino | hardware-help
  Keypad calculator
  Zeruxe — 6/16/24 at 7:25 PM

  From this not-so-good example:
  https://www.hackster.io/nolimitcircuit/arduinolator-an-arduino-calculator-b544ff
*/

#include <Keypad.h>
#include <LiquidCrystal.h>

const byte ROWS = 4;
const byte COLS = 4;
const char keys [ROWS] [COLS] = {
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'.', '0', '=', '/'}
};
const byte rowPins[ROWS] = {23, 25, 27, 29};
const byte colPins[COLS] = {31, 33, 35, 37};
const byte CLEAR_PIN = 39;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

char operandBuffer[2][8];
char operand1[8];
char operand2[8];
//char opKey;
//double dOp1 = 0;
//double dOp2 = 0;
//double result = 0;
int operatorIdx = 0;
int operandIdx = 0;
bool isResult = false;

void checkClear() {
  static int oldState = HIGH;

  int state = digitalRead(CLEAR_PIN);
  if (state != oldState)  {
    oldState = state;
    if (state == LOW) {
      doClear();
    }
    delay(20);  // debounce
  }
}

void doClear()  {
  //Serial.println("Clear");
  lcd.clear();
  //dOp1 = 0;
  //dOp2 = 0;
  operatorIdx = 0;
  operandIdx = 0;
  isResult = false;
}

void setup()  {
  Serial.begin(9600);
  lcd.begin(20, 4);
  pinMode(CLEAR_PIN, INPUT_PULLUP);
  lcd.setCursor(6, 1);
  lcd.print("Arduino");
  lcd.setCursor(5, 2);
  lcd.print("Calculator");
  delay(1000);
  lcd.clear();
}

void loop() {
  char opKey;
  //int operatorIdx = 0;
  double dOp1 = 0;
  double dOp2 = 0;
  double result = 0;

  char key = keypad.getKey();
  checkClear();
  if (key != NO_KEY) {
    if (isResult)   {
      doClear();
      isResult = false;
    }
    Serial.print(key);
    lcd.print(key);
    if (key >= '0' && key <= '9' || key == '.') {
      //Serial.println(" is a number.");
      operandBuffer[operatorIdx][operandIdx] = key;
      operandIdx++;
    } else {
      //Serial.println(" is an operator.");
      operandBuffer[operatorIdx][operandIdx] = '\0'; // terminate operand string
      operandIdx = 0;  // reset buffer index
      if (key != '=') opKey = key;  // save operator
      if (operatorIdx == 0) {
        strncpy(operand1, operandBuffer[0], 8);
        operatorIdx = 1;
      } else  {
        strncpy(operand2, operandBuffer[1], 8);
        operatorIdx = 0;
      }
      dOp1 = atof(operand1);
      dOp2 = atof(operand2);
      //Serial.print("D Op1: ");
      //Serial.println(dOp1);
      //Serial.print("D Op2: ");
      //Serial.println(dOp2);
      if (key == '=') {
        //Serial.print(opKey);
        switch (opKey)  {
          case '+':
            result = dOp1 + dOp2;
            break;
          case '-':
            result = dOp1 - dOp2;
            break;
          case '*':
            result = dOp1 * dOp2;
            break;
          case '/':
            result = dOp1 / dOp2;
            break;
          default:
            break;
        }
        //Serial.print("= ");
        Serial.println(result);
        lcd.print(result);
        isResult = true;
        operatorIdx = 0;
      }
    }
  }
}
$abcdeabcde151015202530354045505560fghijfghij
Clear