Skip to content

Instantly share code, notes, and snippets.

@ReiFan49
Created March 5, 2016 15:29
Show Gist options
  • Save ReiFan49/b6e980f3a83dcd8a9f59 to your computer and use it in GitHub Desktop.
Save ReiFan49/b6e980f3a83dcd8a9f59 to your computer and use it in GitHub Desktop.
[II3231] Arduino Project Files
#if 0
Filename: lcd_calc.ino
Credits:
- http://www.vathsav.com/post/arduino_calculator.html
for the base of the liquidCrystal module workaround
#endif
#include <LiquidCrystal.h>
#include <Key.h>
#include <Keypad.h>
#define ll long long
#define ull unsigned long long
#define Dig09 (100000000LL)
#define Dig10 (1000000000LL)
LiquidCrystal lcd(5,4,3,2,1,0);
const byte
KPRows = 4, KPCols = 4;
char KPKeys[KPRows][KPCols] = {
{'1','2','3','+'},
{'4','5','6','-'},
{'7','8','9','*'},
{'E','0','=','/'}
};
byte
KPRPin[KPRows] = {13,12,11,10},
KPCPin[KPCols] = { 9, 8, 7, 6};
Keypad KPObj = Keypad(makeKeymap(KPKeys),KPRPin,KPCPin,KPRows,KPCols);
#if 0
Weak_Calculator.cpp setup
#endif
char
validOp[] = {
// Initial
0,
// Arithmetic Integral Operation
/*
lhs <op> rhs
(+) performs addition
(-) performs subtraction
(*) performs multiplication
(/) performs integral division
operation result stored in lhs
*/
'+', '-', '*', '/', '=',
// Memory Manipulating Operation
/*
<op> lhs
(M+) performs memory addition
(M-) performs memory subtraction
(MS) performs memory replacement
(MR) performs memory recall
(MC) performs memory clear
any memory operation always returns the lhs
*/
'p', 'm', 's', 'r', 'c',
// State-clearing Operation
/*
<op>
(CC) clear numeric state
* allows for returning the state without clearing memory
* cannot reset any error state
(CE) clear error state
* allows state clearing like restarting the program
* resets any memory and errors
(CX) exit
*/
'C', 'E', 'X'
},
opChoice[] = {
'?', '+', '-', '*', '/', 'C', 'E'
},
*errorStr[] = {
"",
"ZeroDivision",
"Overflow",
"Overflow"
};
char cop;
bool rin=false;
char key;
char err=0;
long lhs=0,rhs=0;
char slhs[16],srhs[16],serr[16];
#if 0
#endif
void setup() {
lcd.begin(16,2);
lcd.print("Welcome");
delay(500);
KPObj.setHoldTime(500);
KPObj.setDebounceTime(30);
}
void loop() {
process_lcd();
char key = KPObj.waitForKey();
input_digits(key);
input_operator(key);
process_var();
delay(5);
}
int input_digits(char key){
char dgg = key >= 0x30 && key < 0x3a;
if(!err && dgg){
long *valp;
valp = (!cop) ? (&lhs) : (&rhs);
rin = !!cop;
if(*valp >= Dig09) {
err = 2 + rin;
} else {
*valp = ((*valp) % Dig09) * 10 + (key - 0x30);
return 0;
}
}
return err;
}
int input_operator(char key){
char opi=0,opg=false;
int retval = 0;
for(;opi <= 13;opi++)
opg |= validOp[opi] == key;
if(opg){
switch(key){
case 'E':
err=0;
case 'C':
lhs=rhs=cop=rin=key=0;
retval = err;
break;
default:
if(err)
return err;
if(cop&&(rhs||rin)){
retval = calculate_operation();
}
if(retval) return retval;
if(key=='='){
rin = 0;
return 0;
}else{
cop = key;
}
rhs=rin=false;
break;
}
}
return retval;
}
int calculate_operation() {
ll llhs = lhs, lrhs = rhs, lres = 0;
switch(cop){
case '+': lres = llhs + lrhs; break;
case '-': lres = llhs - lrhs; break;
case '*': lres = llhs * lrhs; break;
case '/':
if(!rhs)
err=1;
else
lres = llhs / lrhs;
break;
}
if(abs(lres) >= Dig10) {
err=3;
return 3;
} else {
lhs = (long)lres;
}
return 0;
}
void process_var() {
lhs %= Dig10;
rhs %= Dig10;
sprintf(slhs,"%15ld",lhs);
sprintf(srhs,"%15ld",rhs);
sprintf(serr,"%15s",err);
if(err) {
char* sref;
strcpy(serr,errorStr[err]);
switch(err){
case 2:
sref = slhs;
break;
default:
sref = srhs;
}
strcpy(sref,serr);
}
}
void process_lcd() {
lcd.clear();
lcd.setCursor(0,0);
if(cop) lcd.print(cop);
lcd.setCursor(0,1);
if(err) lcd.print('E');
lcd.setCursor(2,0);
lcd.print(slhs);
lcd.setCursor(2,1);
lcd.print(srhs);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment