/**
Arduino Calculator
Description:
This Arduino project implements a basic calculator using a LiquidCrystal display
and a 4x4 keypad. It supports basic arithmetic operations: addition, subtraction,
multiplication, and division.
*/
#include <LiquidCrystal.h> // Library for LCD display
#include <Keypad.h> // Library for keypad input
#include <Servo.h> // Library for servo control (included but not used in this code)
// -------------------- Hardware Configuration --------------------
// Initialize the LiquidCrystal library with the interface pins.
// (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Define the number of rows and columns for the keypad
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
// Assign Arduino pins to the keypad rows and columns
byte rowPins[KEYPAD_ROWS] = {5, 4, 3, 2}; // Connect to the row pinouts of the keypad
byte colPins[KEYPAD_COLS] = {A3, A2, A1, A0}; // Connect to the column pinouts of the keypad
// Define the keys on the keypad
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}
};
// Initialize the Keypad library with the keymap and pin configuration
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
// -------------------- Global Variables --------------------
// Stores the first operand or the result
String memory = "";
// Stores the current input from the user
String current = "";
// Stores the selected arithmetic operation
char operation = 0;
// Flag to track if a decimal point has been entered
bool decimalPoint = false;
// -------------------- Function Definitions --------------------
/**
Displays the splash screen with a welcome message and the word "Calculator".
Each character of "Calculator" appears with a slight delay for a typing effect.
*/
void showSplashScreen() {
lcd.print("Calculator");
lcd.setCursor(3, 1);
String message = "by hayooshkah";
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(120); // Delay between each character
}
delay(500); // Wait before clearing the screen
}
/**
Toggles the cursor visibility to create a blinking effect.
*/
void updateCursor() {
// Blink the cursor every 250 milliseconds
if ((millis() / 250) % 2 == 0) {
lcd.cursor(); // Show cursor
} else {
lcd.noCursor(); // Hide cursor
}
}
/**
Performs the calculation based on the selected operation.
@param operation The arithmetic operation ('+', '-', '*', '/')
@param left The left operand
@param right The right operand
@return The result of the operation
*/
double calculate(char operation, double left, double right) {
switch (operation) {
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
case '/':
if (right != 0) {
return left / right;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Error: Div 0");
return 0;
}
default: return 0;
}
}
/**
Processes the input key pressed by the user.
@param key The key character pressed
*/
void processInput(char key) {
// Handle negative sign for the first number
if (key == '-' && current == "") {
current = "-";
lcd.print("-");
return;
}
switch (key) {
// If an operation key is pressed
case '+':
case '-':
case '*':
case '/':
if (operation == 0) { // If no operation is selected yet
memory = current; // Store the current input as the first operand
current = ""; // Reset current input
}
operation = key; // Set the selected operation
lcd.setCursor(0, 1); // Move cursor to the second line
lcd.print(key); // Display the operation
lcd.setCursor(current.length() + 1, 1); // Move cursor after the operation
return;
// If the equals key is pressed
case '=':
if (operation != 0 && memory != "" && current != "") {
double leftNum = memory.toDouble(); // Convert stored memory to double
double rightNum = current.toDouble(); // Convert current input to double
double result = calculate(operation, leftNum, rightNum); // Perform calculation
memory = String(result); // Store the result in memory
current = ""; // Reset current input
lcd.clear(); // Clear the display
lcd.setCursor(1, 0); // Set cursor to the first line
lcd.print(memory); // Display the result
lcd.setCursor(0, 1); // Move cursor to the second line
lcd.print(operation); // Display the operation
}
return;
}
// Prevent multiple decimal points
if (key == '.' && current.indexOf('.') >= 0) {
return;
}
// Handle leading zero
if (key != '.' && current == "0") {
current = String(key);
} else if (key) {
current += String(key); // Append the pressed key to current input
}
lcd.print(key); // Display the pressed key
}
// -------------------- Arduino Setup and Loop --------------------
/**
The setup function runs once when the Arduino starts.
It initializes serial communication, the LCD, and displays the splash screen.
*/
void setup() {
Serial.begin(115200); // Initialize serial communication for debugging (optional)
lcd.begin(16, 2); // Initialize the LCD with 16 columns and 2 rows
showSplashScreen(); // Display the splash screen
lcd.clear(); // Clear the LCD display
lcd.cursor(); // Show the cursor
lcd.setCursor(1, 0); // Set cursor to the first line, second character
}
/**
The loop function runs continuously after setup().
It updates the cursor and checks for keypad input.
*/
void loop() {
updateCursor(); // Update the cursor blinking
char key = keypad.getKey(); // Get the pressed key from the keypad
if (key) { // If a key is pressed
processInput(key); // Process the input
}
}