// Include the libraries:
// LiquidCrystal_I2C.h: https://github.com/johnrickman/LiquidCrystal_I2C
#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD
#include <Keypad.h> // Library for Keypad
// User Marco
#define MAX 32 // Max size of stack
// ==== Init Part ====
// View Init
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
// Control Init
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', '+' },
{ '4', '5', '6', '-' },
{ '7', '8', '9', '*' },
{ '.', '0', '#', '/' }
};
uint8_t colPins[COLS] = { 8, 7, 6, 5 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 12, 11, 10, 9 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Model Init
/*
`p` points to the edited number;
`stack` stores the numbers
*/
int stack[MAX];
int *p;
void setup() {
// Initiate the LCD:
lcd.init();
lcd.backlight();
// Serial setup
Serial.begin(9600); // 9
// while (!Serial);
Serial.println("\nSimple Calculator");
// stack setup
p = stack;
}
void loop () {
// Model
// View
// Control
if (handle_input()) refresh_lcd();
}
// View Functions
void refresh_lcd() {
int *p0, row;
p0 = stack;
row = 0;
lcd.clear();
if (p - p0 >= 1) {
lcd.setCursor(1, row);
lcd.print(*(p - 1));
row++;
}
lcd.setCursor(0, row);
lcd.print('>');
lcd.print(*p);
}
// Control Functions
int handle_input () {
char c = keypad.getKey();
// no key press
if (c == NO_KEY) return false;
// number input
if ('0' <= c && c <= '9') *p = (*p) * 10 + (c - '0');
// add number to stack
if (c == '#') append_stack();
// operations
if (c == '+') add();
if (c == '-') sub();
if (c == '*') mul();
if (c == '/') div();
return true;
}
void append_stack () {
// test if appendable
p++;
*p = 0;
}
void add () {
*(p - 1) = *(p - 1) + *p;
*p = 0;
}
void sub () {
*(p - 1) = *(p - 1) - *p;
*p = 0;
}
void mul () {
*(p - 1) = *(p - 1) * *p;
*p = 0;
}
void div () { // divide INT; TODO: float
*(p - 1) = *(p - 1) / *p;
*p = 0;
}