#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <DS1307RTC.h> // Include the DS1307 RTC library
#include <TimeLib.h> // Include the TimeLib library
const int buzzerPin = 10; // Buzzer pin
float currentValue = 0.0; // Store the current number
float previousValue = 0.0; // Store the previous number
char operation = '+'; // Store the current operation
String inputAmount = ""; // Store the current input string
// Define keypad layout (4x4)
const byte ROW_NUM = 4; // four rows
const byte COLUMN_NUM = 4; // four columns
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'C', '0', '=', '/'}
};
// Pin connections to Arduino
byte pin_rows[ROW_NUM] = {9, 8, 7, 6}; // Rows 1-4
byte pin_column[COLUMN_NUM] = {5, 4, 3, 2}; // Columns 1-4
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
// Initialize LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Idle timer
unsigned long lastActivityTime = 0;
const unsigned long idleTimeout = 10000; // Turn off backlight after 10 seconds of inactivity
void setup() {
lcd.begin(16, 2); // Set up the LCD's number of columns and rows
lcd.setBacklight(1); // Turn on the LCD backlight
lcd.clear();
pinMode(buzzerPin, OUTPUT); // Set up the buzzer
// Initialize the RTC from DS1307
if (!RTC.isRunning()) {
lcd.clear();
lcd.print("RTC not found!");
while (1); // Stop execution if RTC is not found
}
// Uncomment to set the RTC time when it's not set yet (only needed once)
// RTC.setTime(10, 30, 0); // Set the time: 10:30:00
// Display the initial screen
displayHomeScreen();
}
void loop() {
char key = keypad.getKey();
if (key) {
lastActivityTime = millis(); // Reset the idle timer on activity
if (key == 'C') {
// Clear current input and reset calculator
currentValue = 0.0;
previousValue = 0.0;
operation = '+';
inputAmount = "";
lcd.clear();
lcd.print("Cleared");
delay(1000);
displayCurrentInput();
}
else if (key == '=') {
// Perform the operation and calculate the result
performOperation();
tone(buzzerPin, 1500, 200); // Buzzer feedback for result
}
else if (key == '+' || key == '-' || key == '*' || key == '/') {
// Save the current value and set the operation
if (inputAmount.length() > 0) {
currentValue = inputAmount.toFloat();
inputAmount = "";
}
operation = key;
tone(buzzerPin, 1000, 200); // Buzzer feedback for operation
lcd.clear();
lcd.print("Op: ");
lcd.print(operation);
displayCurrentInput();
}
else {
// Append the key to the input amount and display it
if (key >= '0' && key <= '9') {
inputAmount += key;
displayCurrentInput();
tone(buzzerPin, 1000, 200); // Buzzer feedback for key press
}
}
}
// Check if idle for more than the timeout duration
if (millis() - lastActivityTime > idleTimeout) {
lcd.setBacklight(0); // Turn off the LCD backlight after idle timeout
} else {
lcd.setBacklight(1); // Ensure backlight is on during activity
}
// Display the clock and update every second
displayClock();
}
void displayHomeScreen() {
lcd.clear();
lcd.setBacklight(1);
lcd.print("ELKILEN STORE");
delay(2000);
}
void displayCurrentInput() {
lcd.clear();
lcd.print("Input: Rp");
lcd.print(inputAmount);
}
void displayClock() {
// Get the current time using TimeLib functions
time_t currentTime = RTC.get(); // Get the current time from the RTC
// Use TimeLib functions to extract the hour, minute, and second
int h = hour(currentTime); // Get the current hour
int m = minute(currentTime); // Get the current minute
int s = second(currentTime); // Get the current second
// Display the time on the LCD
lcd.setCursor(0, 1);
lcd.print(h);
lcd.print(":");
lcd.print(m);
lcd.print(":");
lcd.print(s);
}
void performOperation() {
float result = 0.0;
// Convert the current input to a float value
if (inputAmount.length() > 0) {
currentValue = inputAmount.toFloat();
inputAmount = ""; // Clear the input string
}
// Perform the operation
switch (operation) {
case '+':
result = previousValue + currentValue;
break;
case '-':
result = previousValue - currentValue;
break;
case '*':
result = previousValue * currentValue;
break;
case '/':
if (currentValue != 0) {
result = previousValue / currentValue;
} else {
lcd.clear();
lcd.print("Error: Div by 0");
delay(1000);
displayCurrentInput();
return;
}
break;
}
// Show the result on the LCD and store it as the previous value for next operation
previousValue = result;
lcd.clear();
lcd.print("Result: Rp");
lcd.print(result, 0); // Display result with no decimal points for Rupiah
}