Basic Calculator

Hello, a few weeks ago I was looking for a code to make a basic calculator using Arduino uno, 16x2 LCD and a 4x4 keyboard but there were only things that were too basic and messy. I set myself the task of doing it on my own and I finally have a code with which it will work correctly, it makes accounts with decimal numbers if applicable and a cursor like in common calculators. Without further ado, I leave it here. Thank you :heart:

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

const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'X', '0', '=', '/'}
};

byte rowPins[ROWS] = {3, 2, 1, 0};
byte colPins[COLS] = {7, 6, 5, 4};

LiquidCrystal lcd(9, 8, 10, 11, 12, 13);
Keypad myKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

boolean valorActual = false;
boolean siguiente = false;
boolean final = false;
String num1, num2, num3;
float resultado;
int movimiento;
char op;
int cursorPos = 0; // Cursor Position
unsigned long lastBlinkMillis = 0;
const int blinkInterval = 500; // Flashing interval
boolean cursorVisible = true;
boolean mostrarCursor = true; // Control to show/hide the cursor

void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("ProyectBy");
  lcd.setCursor(0, 1);
  lcd.print("Gavan♡");
  delay(1700);
  lcd.clear();
}

void loop() {
  char key = myKeypad.getKey();
  unsigned long currentMillis = millis();

  if (key != NO_KEY && (key == '1' || key == '2' || key == '3' || key == '4' || key == '5' || key == '6' || key == '7' || key == '8' || key == '9' || key == '0')) {
    if (valorActual != true) {
      num1 = num1 + key;
      int numLength = num1.length();
      movimiento = numLength;
      lcd.setCursor(0, 0);
      lcd.print(num1);
      cursorPos = numLength; // Move the cursor +1
    } else {
      num2 = num2 + key;
      int numLength = num2.length();
      lcd.setCursor(movimiento + 1, 0);
      lcd.print(num2);
      cursorPos = movimiento + 1 + numLength; // Move the cursor +1
      final = true;
    }
  } else if (valorActual == false && key != NO_KEY && (key == '/' || key == '*' || key == '-' || key == '+')) {
    if (valorActual == false) {
      valorActual = true;
      op = key;
      lcd.setCursor(movimiento, 0);
      lcd.print(op);
      cursorPos = movimiento + 1; // Move the cursor +1
    }
  } else if (final == true && key != NO_KEY && key == '=') {
    mostrarCursor = false; // Hide cursor when press '='

    if (op == '+') {
      resultado = num1.toFloat() + num2.toFloat();
    } else if (op == '-') {
      resultado = num1.toFloat() - num2.toFloat();
    } else if (op == '*') {
      resultado = num1.toFloat() * num2.toFloat();
    } else if (op == '/') {
      if (num2.toFloat() == 0) {
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Sintax Error");
        delay(2000);
        lcd.clear();
        num1 = "";
        num2 = "";
        valorActual = false;
        final = false;
        cursorPos = (0,0); // Reset cursor
        mostrarCursor = true;
        return;
      } else {
        resultado = num1.toFloat() / num2.toFloat();
      }
    }

    num3 = String(resultado, 8);

    // Delete decimal
    num3.remove(num3.length() - 1, 1);
    while (num3.endsWith("0")) {
      num3.remove(num3.length() - 1, 1);
    }

    // Delete decimal point
    if (num3.endsWith(".")) {
      num3.remove(num3.length() - 1, 1);
    }

    // Show answer
    int espacios = 16 - num3.length();
    lcd.setCursor(espacios, 1);
    lcd.print(num3);

    // Clear variables and reset flags
    num1 = "";
    num2 = "";
    valorActual = false;
    final = false;
  } else if (key != NO_KEY && key == 'X') {
    lcd.clear();
    valorActual = false;
    final = false;
    num1 = "";
    num2 = "";
    cursorPos = 0; // Reset cursor
    mostrarCursor = true; // Reset cursor when press 'X'
  }

  // Cursor flashing
  if (mostrarCursor && currentMillis - lastBlinkMillis >= blinkInterval) {
    lastBlinkMillis = currentMillis;
    cursorVisible = !cursorVisible;
    lcd.setCursor(cursorPos, 0);
    if (cursorVisible) {
      lcd.write('_'); 
    } else {
      lcd.write(' '); 
    }
  }
}

That can be a lot shorter :wink:

if(key >= '0' && key <= '9') {

There are a few more that you can do.

Because you don't have a problem with the IDE, I have moved your topic to a more suitable location on the forum.

1 Like

The following sketch simulates a Calculator by taking commands (+, -, *, /) and data from Keypad and showing the result on Seial Moniotr. You may modify it to show the result on LCD.

//#include <Key.h>
#include <Keypad.h>
const byte rows = 4;
const byte columns = 4;

char first_Number[3] = {0};
char second_Number[3] = {0};
int i, j;
char user_input;


char keyboard[rows][columns] =
{
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '/'},
  {'C', '0', '=', '*'}
};

byte  rowsPins[rows] = {9, 8, 7, 6};
byte columnsPins[columns] = {5, 4, 3, 2};


Keypad keys = Keypad(makeKeymap(keyboard), rowsPins, columnsPins, rows, columns);

void setup()
{
  Serial.begin(9600);
  Serial.print("Enter First 2-digit Number: ");
}

void loop()
{
  user_input = keys.getKey();
  if (user_input != 0)
  {
    first_Number[i] = user_input;
    Serial.print(first_Number[i]);
    i++;
    if (i == 2)
    {
      byte firstNumber = atoi(first_Number);
      Serial.println();
      //Serial.println(firstNumber);
      //---------------------------
      Serial.print("Enter Second 2-digit Number: ");
      do
      {
        user_input = keys.getKey();
        if (user_input != 0)
        {
          second_Number[j] = user_input;
          Serial.print(second_Number[j]);
          j++;
          if (j == 2)
          {
            byte secondNumber = atoi(second_Number);
            Serial.println();
            //Serial.println(secondNumber);
            //-----------------------------
            Serial.print("Enter Opearation: ");
            do
            {
              user_input = keys.getKey();
              if (user_input != 0)
              {
                Serial.print(user_input);
                Serial.println();
                //------------------------
                switch (user_input)
                {
                  case '+':
                    Serial.print("Sum is: ");
                    Serial.println(firstNumber + secondNumber);
                    break;
                  case '-':
                    Serial.print("Difference is: ");
                    Serial.println(firstNumber - secondNumber);
                    break;
                  case '*':
                    Serial.print("Multiplication is: ");
                    Serial.println(firstNumber * secondNumber);
                    break;
                  case '/':
                    Serial.print("Dividend is: ");
                    Serial.println(firstNumber / secondNumber);
                    break;
                  default:
                    Serial.print("Undefined!");
                    while (1);
                }
              }
            }
            while (!user_input);
          }
        }
      }
      while (i != 4);
    }
  }
}

Why 'X' and no '.' or ',' for decimals?

Curious that you comment in proper English with lead letter upper case, but text and random variables in Spanish.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.