Created
March 5, 2016 15:29
-
-
Save ReiFan49/b6e980f3a83dcd8a9f59 to your computer and use it in GitHub Desktop.
[II3231] Arduino Project Files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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