/* EEE20003 Project Progress - Part 1
Group 39 Project G
Authors: B Horvath, M Mahood, K Rhodes
Program is a calculator that can complete basic operations, being:
- addition, subtraction and multiplication
- taking input of integers or doubles
- can do calculation with previous result (or without)
- can power on and off, clearing when turned off
- can take up to 100 values (+-* count as a value)
*/
#include <Keypad.h> //includes library for keypad operation
#include <LiquidCrystal_I2C.h> //includes library for lcd
LiquidCrystal_I2C lcd(0x27,20,4); //Initialises the LCD.
const uint8_t ROWS = 4;
const uint8_t COLS = 4; //gives the keypad 4 rows and 4 columns
char keys[ROWS][COLS] = {
{ '1', '2', '3', '+' },
{ '4', '5', '6', '-' },
{ '7', '8', '9', '*' },
{ 'P', '0', '.', '=' } //specifies the possible 'keys' values, as characters.
};
uint8_t colPins[COLS] = { 22, 24, 26, 28 }; // Pins connected to C1, C2, C3, C4.
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 }; // Pins connected to R1, R2, R3, R4.
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//^^initialises the keypad.^^
String userin = ""; //sets userin to be a empty string.
double userinarray[100]={}; //100 'slot' long array for storing user input.
double hold[100]={}; //second array for holding user input, when above array is
// being cleared between operations.
int ArraySlot=0; //array element ('slot') marking variable, used to find specific
// array slots for computation.
bool on = false; //whether or not the LCD is on (serves as a safety).
bool equalsPressed = false; //whether or not the user has pressed equals.
float ans = 0; //the answer for the expression the user has entered; 0 default.
void setup() {
Serial.begin(9600);
lcd.begin(16, 2); //specifies width and height of LCD.
lcd.noBacklight(); //turns off the backlight of the LCD.
pinMode(39, OUTPUT);
digitalWrite(39,HIGH);
pinMode(41, OUTPUT);
digitalWrite(41,HIGH);
pinMode(43, OUTPUT);
digitalWrite(43,HIGH);
pinMode(45, OUTPUT);
digitalWrite(45,HIGH);
attachInterrupt(0,row1,RISING);
attachInterrupt(1,row2,RISING);
attachInterrupt(5,row3,RISING);
attachInterrupt(4,row4,RISING);
}
void row1(){
Serial.println("Row 1");
}
void row2(){
Serial.println("Row 2");
}void row3(){
Serial.println("Row 3");
}void row4(){
Serial.println("Row 4");
}
void loop() {
char key = keypad.getKey(); //sets 'key' equal to the ASCII code equivalent to
// the key being pressed by the user.
if (key != NO_KEY && on == true) { //if a key is pressed, AND the LCD is on:
if (equalsPressed == true){ //if the equals key is pressed:
userin = ""; //user input string is cleared.
for (int clearSlot = 0; clearSlot<101; clearSlot++){ //itterates through
// the user input, and second hold array, setting each slot to be blank.
userinarray[clearSlot] = {};
hold[clearSlot] = {};
}
ArraySlot=0; //goes back to the start of the user input array.
lcd.clear(); //LCD contents are cleared.
equalsPressed = false; //sets equalsPressed to false, breaking the if statement.
if (key == '+' || key == '-' || key == '*'){
lcd.print(ans); //if an operator is pressed after the equals key, the answer
// previously calculated is displayed, so user knows the value they're operating.
}
}
lcd.print(key); //key entered by user is displayed.
on = true; //bool for LCD power is set 'on' (relevent later).
if (key == '='){ //if equals is pressed:
lcd.clear(); //LCD screen is cleared.
userinarray[ArraySlot]=userin.toDouble(); //arrayslot outputs of the user in array
// are set to be double datatype numbers (for extra precision).
for (int ArraySlot=0; ArraySlot<101; ArraySlot++){
if (userinarray[ArraySlot] == '*'){ //itterates through the user input array,
// checking for symbols signifying multiplication (*).
double multiply = (userinarray[ArraySlot-1]*userinarray[ArraySlot+1]);
//^^once an * is found in some array 'slot', the slots immediately to the left
// and right of the slot with '*' are multiplied; this is saved in the variable
// called 'multiply' (datatype double).^^
int HoldSlot = 0; //second storage array 'slot' marking variable, is set to
// equal 0 (meaning it will start searching through the array from the first
// slot in the array).
while(HoldSlot < ArraySlot-1){ //while the HoldSlot is less than the current
// Array slot - 1 then the following lines run.
// eg if userinarray = 11 - 5 * 7 + 2, array slot would equal 3 as that is
// determined in the if statement in line 73 therefore loop runs for 0 1 2
hold[HoldSlot] = userinarray[HoldSlot]; //value at slot the loop is up to
// within the user array, set to the value for the hold array at the same slot
HoldSlot++;//increases increment for array slot to continue through the loop
// eg if userinarray = 11 - 5 * 7 + 2
// would set hold = 11 -
}
hold[HoldSlot] = multiply; // sets the next hold value in array to the result of
// the multiplication completed above
// eg if userinarray = 11 - 5 * 7 + 2 would take the 5 * 7 = 35 and add
// 35 to end of hold array, therefore hold = 11 - 35
HoldSlot++; // increases increment of position in hold array
while(HoldSlot < 101){ //while the hold array is not full
hold[HoldSlot] = userinarray[HoldSlot + 2]; // hold value is set to the value
//in user in array that is beyond the section of calculation taking place
//eg if userinarray = 11 - 5 * 7 + 2 and hold already set to 11 - 35 then
//now hold = 11 - 35 - 2
HoldSlot++; // increments hold slot to continue through while loop
}
for(int slot=0; slot<99; slot++){ //sets a new variable to increment through slots
userinarray[slot] = hold[slot]; //sets the values in hold array to the user in
// array slot for slot.
}
ArraySlot = 0; // resets the array slot so that on next run restarts for loop
// so that calculator can handle numerous operations of the same type in
//one equatin and in the correct order of operations
}
}
for (int ArraySlot=0; ArraySlot<101; ArraySlot++){ //identical to the previous
// multiplication section starting on line 72 above, except this one checks for
// and completes addition and subtraction (+ and -).
if (userinarray[ArraySlot] == '+'){ //addition is checked for - identical
// to line 64 above, but for adding values.
double addition = (userinarray[ArraySlot-1] + userinarray[ArraySlot+1]);
int HoldSlot = 0;
while(HoldSlot < ArraySlot-1){
hold[HoldSlot] = userinarray[HoldSlot];
HoldSlot++;
}
hold[HoldSlot] = addition;
HoldSlot++;
while(HoldSlot < 101){
hold[HoldSlot] = userinarray[HoldSlot + 2];
HoldSlot++;
}
for(int slot=0; slot<99; slot++){
userinarray[slot] = hold[slot];
}
ArraySlot = 0;
}
else if (userinarray[ArraySlot] == '-'){ //subtraction is checked for - identical
// to line 73 and 116 above, but for subtracting values.
double subtract = (userinarray[ArraySlot-1] - userinarray[ArraySlot+1]);
int HoldSlot = 0;
while(HoldSlot < ArraySlot-1){
hold[HoldSlot] = userinarray[HoldSlot];
HoldSlot++;
}
hold[HoldSlot] = subtract;
HoldSlot++;
while(HoldSlot < 101){
hold[HoldSlot] = userinarray[HoldSlot + 2];
HoldSlot++;
}
for(int slot=0; slot<99; slot++){
userinarray[slot] = hold[slot];
}
ArraySlot = 0;
}
}
lcd.print(userinarray[0]); //the first slot of the user input array (the answer)
// is displayed to the user.
ans = userinarray[0]; //answer is set to the first value of the user input array,
// thus saving this value if the user wants to further operate on it.
equalsPressed = true; //sets equals pressed true, thus preparing for the next
// equals press.
}
else if (key == 'P'){ //if the power button is pressed (ie not the equals button):
on = false; //LCD on bool is set false
lcd.clear(); //LCD display is cleared.
lcd.noBacklight(); //LCD backlight is turned off.
userin = ""; //user input is cleared (set empty).
for (int clearSlot = 0; clearSlot<101; clearSlot++){
userinarray[clearSlot] = {};
hold[clearSlot] = {}; //both the storage arrays are cleared.
}
ArraySlot=0; //user in array slot marker is set back to the beginning of the array,
// making it ready for next use.
equalsPressed = false; //equals pressed is set to false, ensureing the calculator
// cannot continue to be used after it has bee "turned off".
}
else if (key == '+' || key == '-' || key == '*'){ //if operation buttons have been
// pressed (ie not the equals or power buttons):
if (userin == ""){ //if the user input is empty:
userinarray[ArraySlot] = ans;
ArraySlot++; //the user input array is has it's current slot set to the
// pervious answer, and then moves directly to the next slot for more entries
// (thus allowing the old answer to be saved as a value the user can operate on).
} else { //if the user input isn't empty:
userinarray[ArraySlot]=userin.toDouble();
ArraySlot++; //the user input is saved to the current array slot, and the array
// marker is then moved to the next slot.
}
userinarray[ArraySlot]=key; //the operator is then saved in this new (empty) slot.
ArraySlot++; //moves to next array slot, preventint 2 operators being grouped.
userin = ""; //user input is cleared, ready for more entries.
}
else {
userin = userin + key; //allows multiple numbers to be stored in the one array
// slot (meaning double and greater digit numbers can be input).
}
} else if (key == 'P'){ //if the power button is pressed(and equals hasn't yet been
// pressed):
on = true; //LCD on bool set true.
lcd.backlight(); //LCD is turned on.
ans = 0; //any previous answer stored is cleared.
}
}