#include <LiquidCrystal.h>//including the LCD libary for the project
#include <Keypad.h> //including the keypad libary for the project
LiquidCrystal lcd(8,9,10,11,12,13);
const byte ROWS = 4; //setting the amount of rows on the keypad
const byte COLM = 4; //setting the amount of columns on the keypad
char keys[ROWS][COLM] = //setting the keys depending on the number of rows and colums
{
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '#', '/'}
};
byte rowPins[ROWS] = {0,1,2,3}; //defining the letters to GPIO pins of Arduino
byte colmPins[COLM] = {4,5,6,7};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colmPins, ROWS, COLM); //compiles all the arrays to create a keypad object
float inputs[3]; //array used to store inputs entered by user for two numbers
bool inputs_entered[3]; //array used for Arduino to see whether two inputs have been entered
bool inputs_displayed[3]; //array used to inform Arduino whether the typed information has been printed
char arithmetic_op; //character datatype used to store input entered by user for operation
bool arithmetic_op_entered = false; //boolean datatype used for Arduino to see whether the input has been entered
bool arithmetic_op_displayed = false; //boolean datatype used to inform Arduino whether the typed information has been printed
void setup() {
Serial.begin(9600); //opening the serial communication channel at baud rate 9600(9600 bits)
lcd.begin(16,2); //setting up the LCD's number of columns and rows
lcd.setCursor(0,0);
lcd.print("Math calculator");
delay(1000);
lcd.clear();
ResetValues(); //function for resetting value
Calculator(); //function for calculating answer and displaying the result
}
void loop() {} //void loop is not being used but has to be kept in sketch for....well reasons
void ResetValues() //function for resetting value
{
for (int i = 0; i < 3; i++) //for statement that runs whatever in the curly brackets twice; creates integer variable iteration(i), if (i) is less than 2[do whatever], add 1 to i
{
inputs_entered[i] = false; //inside the array, depending on the iteration, change the value(true) to false(as the iteraton increments so does the value being checked so both values are made false for resetting everything
inputs_displayed[i] = false; //once again(look above) resetting the value
inputs[i] = 0; //as this is a float, we cannot say false or true so instead we just set it back to 0 as a way to flush the value
}
arithmetic_op = NULL; // as it is a charcter, we cannot change the value inside to true or 0, instead null(in my opinion a form of saying no value, it's undefined, etc)
arithmetic_op_entered = false; //similar to above we are simply resetting the values and whether they have been entered
arithmetic_op_displayed = false; //resetting value
}
void Calculator()
{
ResetValues();//function for resetting
GetInputs(); //function for getting value from keypad
GetOperator();//function for getting operator value from keypad
switch (arithmetic_op) { //plugging operator from GetOperator function via a switch statement to complete functions
case '+':
lcd.print(inputs[0] + inputs[1]+inputs[2]);
delay(1000);
lcd.clear();
break;
case '-':
lcd.print(inputs[0] - inputs[1] -inputs[2]);
delay(1000);
lcd.clear();
break;
case '*':
lcd.print(inputs[0] * inputs[1] * inputs[2]);
delay(1000);
lcd.clear();
break;
case '/':
lcd.print(inputs[0] / inputs[1] / inputs[2]);
delay(1000);
lcd.clear();
break;
}
delay(100); //delay for 100 miliseconds
Serial.flush(); //flush potentional values from serial monitor
Calculator(); //calling function again, [looping]
}
void GetInputs() //function for getting inputs
{
while (!inputs_entered[0]) { //whilst inputs entered(variable used to store whether two values have been entered) is false
for (int i = 0; i < 3; i++) //looping contents twice as shown before(you may be asking how we are using the same variable again, we are not, this is a local variable not global, so we can use the same name again, further help in comments)
{
if (!inputs_entered[i] && !inputs_displayed[i]) //if inputs entered and inputs displayed are false
{
lcd.print("Input " + String(i) + ": "); //displaying what input it is for the number is via using the iteration from the for loop
inputs_displayed[i] = true; //setting display value to true, we have completed printing a line of input 1 or 2
while (!inputs_entered[i]) // if inputs_entered(from the two values inside) is false, get values
{
char customKey = keypad.getKey(); //getting value from keypad
if (customKey != NO_KEY) // if there is a output which is not a blank space(a keypad outputs responses even if there is no button press, resulting in "empty" values) we get around this via using this "function"
{
customKey = convertValues(customKey); //as the value outputed is a character, in order to do arithmetic calculations, we must convert it to a integer
inputs[i] = customKey; //depending on what iteration we are on add the corrosponding letter to the inputs array
lcd.print(inputs[i]); //printing the value
delay(1000);
lcd.clear();
inputs_entered[i] = true; //in the array depending on what iteration set the value to true as the process has been completed
}
}
}
}
}
}
void GetOperator()//function for getting operator
{
while (!arithmetic_op_entered) { //process is very similar to above in getting two values to perform arithmetic operations(if anyone is confused, don't hesitate to comment)
if (!arithmetic_op_entered && !arithmetic_op_displayed)
{
lcd.print("Operator: ");
arithmetic_op_displayed = true;
while (!arithmetic_op_entered)
{
char customKey = keypad.getKey();
if (customKey != NO_KEY)
{
arithmetic_op = customKey;
lcd.print(keypad.getKey());
delay(1000);
lcd.clear();
arithmetic_op_entered = true;
}
}
}
}
}
int convertValues(int x) //function used above to convert character value into integer
{
return x - '0'; //returning changed character value now to integer value
}