#include <LiquidCrystal.h> // include the library for the LCD
#include <Keypad.h> // include the library for the Keypad
//keypad variables
const byte KEYPAD_ROWS = 4; // defines the number of rows on the keypad
const byte KEYPAD_COLS = 4; // defines the number of columns on the keypad
byte rowPins[KEYPAD_ROWS] = {5, 4, 3, 2}; // defines which pins are mapped to which rows
byte colPins[KEYPAD_COLS] = {A3, A2, A1, A0}; // defines which pins are mapped to which columns
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}
}; // correlates to the values on the keys
LiquidCrystal lcd(12, 11, 10, 9, 8, 7); // states which pins the LCD are connected to on the Arduino
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS); // define an instance of the keypad
void setup()
{
lcd.begin(16, 2); // initialise LCD with width of 16 and height of 2
lcd.clear(); // clears display
lcd.cursor(); // initialise the cursor at the start position
pinMode(6, INPUT_PULLUP); // initialise pin for button
pinMode(13,OUTPUT); // initialise pin for LCD backlight
digitalWrite(13, HIGH); // turn LCD backlight on
}
double calculate(char operation, double left, double right) // performs the calculations
{
switch (operation) {
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
//extra feature
case '/': return left / right;
}
}
int isNum(char a) // determines if key value is an integer
{
// if that char is within correct range on the ASCII table (48 - 57 correlates with numbers 0 - 9)
if ((int)a > 47 && (int)a < 58) {
return 1; // return true (1)
} else {
return 0; // return false (0)
}
}
char keypad_character() // validate when keypad has input
{
char key;
// when no key has been pressed
while((key = keypad.getKey()) == NO_KEY) {
//do nothing
}
// else (ie. when key is pressed)
return key; // return the value of the key pressed
}
char op; // operator variable for when non-number is entered
float keypad_number() // evaluates what character has been pressed and how to store this data (ie. operator or number)
{
String number; // initialise number as string to account for multiple characters in number
char key;
// while true loops means function is repeatedly checking for this when called
while (true) {
key = keypad_character(); // call function to determine value of key
if (!isNum(key) && key != '.') {
// if a non-number is entered (ie. operator is either +,-,*,/,=)
op = key; // assign key value to operator char (stores last pressed operator)
return number.toDouble(); // convert the number value to a decimal (float)
}
lcd.print(key); // print the value of the pressed key to the lcd
number += key; // number is a concatenation of the keys that are pressed in a row when they are all number values
}
}
bool lcdTemp = HIGH; // temporary variable for LCD backlight
bool previousBtnState = HIGH; // previous button state
//function to turn LCD backlight off
void power() {
bool btnState = digitalRead(6); // read in the current button state (detect if button clicked)
// if the current button state is not what the previous state was
if (btnState != previousBtnState) {
previousBtnState = btnState; // set the previous button state equal to current button state
// if the button state is high (clicked)
if (btnState == HIGH) {
lcdTemp = (lcdTemp == LOW) ? HIGH: LOW; // adjust value of lcd backlight accordingly
digitalWrite(13, lcdTemp); // write to lcd backlight pin the value of lcdTemp
}
}
}
void loop()
{
float ans;
float num;
char temp;
//get first number
ans = keypad_number(); // call function to determine what previously entered number was
lcd.print(op); // print operator to lcd
// when the operator is NOT equals
while(op != '=') {
temp = op; // store the previous operator pressed in a temporary variable
num = keypad_number(); // determine the next entered number
lcd.print(op); // print the operator
ans = calculate(temp, ans, num); // calculate the answers based on the left number (ans), operator (op) and right number (num)
}
lcd.clear(); // clear lcd
lcd.println(ans); // print the answer value to screen
delay(3000); // wait 3 seconds
lcd.clear(); // clear display again
}