const byte ROWS = 4; // Number of rows
const byte COLS = 4; // Number of columns

// Define the keypad matrix with hexadecimal inputs
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'E', '0', 'F', 'D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6};     // Connect row pins to Arduino digital pins
byte colPins[COLS] = {5, 4, 3, 2};     // Connect column pins to Arduino digital pins

const byte SW1_PIN = A0; // Switch 1 input pin
const byte SW2_PIN = A1; // Switch 2 input pin
const byte SW3_PIN = A2; // Switch 3 input pin
const byte SW4_PIN = A3; // Switch 4 input pin
const byte EQUALS_PIN = A4; // Equals button input pin

String input = ""; // Input string to store key presses
bool secondOperandSet = false; // Flag to track if the second operand has been set
bool waitingForOperand = false; // Flag to track if waiting for the second operand

void setup() {
  Serial.begin(9600);
  pinMode(SW1_PIN, INPUT_PULLUP);
  pinMode(SW2_PIN, INPUT_PULLUP);
  pinMode(SW3_PIN, INPUT_PULLUP);
  pinMode(SW4_PIN, INPUT_PULLUP);
  pinMode(EQUALS_PIN, INPUT_PULLUP);
}

void loop() {
  char key = getKey();

  if (key != '\0') {
    if (secondOperandSet) {
      // Clear the input string if the second operand is already set
      input = "";
      secondOperandSet = false;
    }
    input += key;
    Serial.print(key);
  }

  if (waitingForOperand) {
    // Only allow operator buttons if waiting for the second operand
    if (digitalRead(SW1_PIN) == HIGH) {
      input += " + ";
      Serial.print(" + ");
      delay(200); // Debounce delay
      waitingForOperand = false; // Reset the flag when the operator is pressed
    }

    if (digitalRead(SW2_PIN) == HIGH) {
      input += " - ";
      Serial.print(" - ");
      delay(200); // Debounce delay
      waitingForOperand = false; // Reset the flag when the operator is pressed
    }

    if (digitalRead(SW3_PIN) == HIGH) {
      input += " * ";
      Serial.print(" * ");
      delay(200); // Debounce delay
      waitingForOperand = false; // Reset the flag when the operator is pressed
    }

    if (digitalRead(SW4_PIN) == HIGH) {
      input += " / ";
      Serial.print(" / ");
      delay(200); // Debounce delay
      waitingForOperand = false; // Reset the flag when the operator is pressed
    }
  }

  if (!waitingForOperand && digitalRead(EQUALS_PIN) == HIGH) {
    if (input.length() > 0) {
      input += " = ";
      Serial.print(" = ");
      delay(200); // Debounce delay
      calculateResult();
      waitingForOperand = true; // Set the flag to true after calculation
      secondOperandSet = true; // Set the flag to true after the second operand is set
    }
  }
}

char getKey() {
  char key = '\0';

  for (byte col = 0; col < COLS; col++) {
    pinMode(colPins[col], OUTPUT);     // Set current column pin to OUTPUT
    digitalWrite(colPins[col], LOW);   // Set current column pin to LOW

    for (byte row = 0; row < ROWS; row++) {
      pinMode(rowPins[row], INPUT_PULLUP);  // Set current row pin to INPUT_PULLUP

      if (digitalRead(rowPins[row]) == LOW) {
        while (digitalRead(rowPins[row]) == LOW) {} // Wait for key release

        // Get the pressed key
        key = keys[row][col];
        break;
      }
    }

    pinMode(rowPins[col], OUTPUT);  // Set current row pin back to OUTPUT
    digitalWrite(rowPins[col], HIGH); // Set current row pin back to HIGH
    pinMode(colPins[col], INPUT);   // Set current column pin back to INPUT
  }

  return key;
}

void calculateResult() {
  int result = 0;
  int remainder = 0;
  int operand1 = 0;
  int operand2 = 0;
  char operatorSymbol = ' ';

  // Parse the input string
  int numChars = input.length();
  int startIndex = 0;
  for (int i = 0; i < numChars; i++) {
    if (input.charAt(i) == '+' || input.charAt(i) == '-' || input.charAt(i) == '*' || input.charAt(i) == '/') {
      operand1 = parseHexNumber(input.substring(startIndex, i));
      operatorSymbol = input.charAt(i);
      startIndex = i + 1;
    }
    else if (input.charAt(i) == '=') {
      operand2 = parseHexNumber(input.substring(startIndex, i));
    }
  }

  // Perform the calculation based on the operator symbol
  switch (operatorSymbol) {
    case '+':
      result = operand1 + operand2;
      break;
    case '-':
      result = operand1 - operand2;
      break;
    case '*':
      result = operand1 * operand2;
      break;
    case '/':
      result = operand1 / operand2;
      remainder = operand1 % operand2;
      break;
  }

  // Print the result and remainder
  Serial.print(String(result, HEX));
  if (operatorSymbol == '/')
    Serial.println(" remainder " + String(remainder, HEX));
  else
    Serial.println();
}

int parseHexNumber(String hexString) {
  hexString.toUpperCase(); // Convert to uppercase
  return strtol(hexString.c_str(), NULL, 16);
}
$abcdeabcde151015202530fghijfghij