# Need help with calculator logic

I am trying to build a calculator with an Arduino, an LCD display, and a keypad. Getting inputs from the keypad is not the issue. Before I can add, subtract, multiply, or divide any two numbers, I want to make sure the calculator registered the given number. I am trying to program it (so far) so that I type in a number and press enter (the @ sign I assigned to my keypad) and the LCD prints out that number. As you will see, I attempted to devise a logic mechanism for the Arduino to recognize the typed number.

I thought since as you type more numbers the value of the first number typed increases by 10 fold each time (if you start by pressing 4 then if you press another number such as 5 following it, that 4 will become 40, and 400 if another number is pressed, etc...) I could multiply that number (and every following number) by 10, 100, 100, etc...

But it doesn't work and I need help so that the number can be collected by the Arduino.

Here's my attempt at it:

``````    #include <LiquidCrystal.h>
#include "Arduino.h"

int count = 0;
int row = 0;
int column = 0;

//const int buzzer = 0;

int value1;
int value2 = 0;

int spot1 = 0;
int spot2 = 0;
int spot3 = 0;
int spot4 = 0;
int spot5 = 0;
int spot6 = 0;
int spot7 = 0;
int spot8 = 0;

LiquidCrystal lcd(1, 2, 3, 4, 5, 6 );

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'%','0','@'}
};
byte rowPins[ROWS] = {10, 9, 8, 7}; //connect to the row pinouts of the
byte colPins[COLS] = {13, 12, 11}; //connect to the column pinouts of
);

void setup() {
//pinMode(buzzer, OUTPUT);
lcd.begin(16,2);
lcd.print("---Calculator---");
delay(2000);
lcd.clear();
lcd.print("Value1: ");

}

void loop() {

if(key != NO_KEY){
lcd.print(key);
if(key != '%' && key != '@'){
count++;
}
else if(count == 1){
spot1 = key;
}
else if(count == 2){
spot2 = key;
}
else if(count == 3){
spot3 = key;
}
else if(count == 4){
spot4 = key;
}
else if(count == 5){
spot5=key;
}
else if(count == 6){
spot6=key;
}
else if(count == 7){
spot7=key;
}
else if(count == 8){
spot8=key;
}

if(key=='@'){
if(count == 1){
value1 = spot1;
}
else if(count == 2){
value1 = (spot1*10)+(spot2);
}
else if(count == 3){
value1 = (spot1*100)+(spot2*10)+spot3;
}
if(count == 4){
value1 = (spot1*1000)+(spot2*100)+(spot3*10)+spot4;
}
if(count == 5){
value1 = (spot1*10000)+(spot2*1000)+(spot3*100)+(spot4*10)+spot5;
}
if(count == 6){
value1 = (spot1*100000)+(spot2*10000)+(spot3*1000)+(spot4*100)+(spot5*10)+spot6;
}
if(count == 7){
}
if(count == 8){
}
lcd.print(value1);
}

if(key  == '%'){
count = 0;
lcd.clear();
lcd.print("Value1: ");
}
}

}
``````

PS: If you know any better way to accomplish this goal, I would love to hear it.

• Instead of storing all the different digits in a whole bunch of variables, why not keep one int variable and keep track of everything in it. Instead of the count++ you just multiply the int by 10 and get ready to add the next digit. – Delta_G Jun 4 '17 at 18:04
• Please be more explicit about what "doesn't work". Your method, while perhaps not very elegant should work, for small numbers anyway. I didn't spot a mistake from a quick glance at the code, but I don't know what I'm looking for. – Mark Smith Jun 4 '17 at 18:35
• the issue is that the calculator outputs 64 regardless of what I entered – Daniel Hendrix Jun 4 '17 at 19:02
• I agree with @Delta_G - accumulate the value as you go instead of collecting digits then assembling them afterwards. I'm not sure why you would get 64 from this, ... Have you tried the accumulator approach? – SDsolar Jun 4 '17 at 23:55

If your keypad setup results in '%' and '@' arriving correctly, then it probably also results in the characters '0', '1', ... '9' arriving when number keys are pressed, rather than digit values 0, 1, ... 9 arriving.

Be that as it may, there's a far simpler approach to building `value1` which does not use a big set of spot values like your method does. Here is an illustration of it.

``````// ... Before number input, zero out a number-accumulator variable
long int nin = 0;

do {
if (key != NO_KEY) {
lcd.print(key);
// As number keys are pressed, add them to tail of number
if (key >= '0' && '9' >= key) {
nin = 10*nin + (key & 0xF);   // Get low 4 bits of key
}
}
if (key == '@') {
lcd.print("Value = ");
lcd.print(nin);
// ... do whatever else with value
// ... then get ready for next value
nin = 0;
}
} while (1);
``````
``````if(key != '%' && key != '@'){
count++;
}
else if(count == 1){
spot1 = key;
}
else if(count == 2){
spot2 = key;
}
``````

You've got a problem here. If key isn't '%' and isn't '@' then you increase count but since all the rest are else if to that then it skips over all of them and never actually puts the digit int the spot.

• I tried removing the else's but it still does not appear to work – Daniel Hendrix Jun 4 '17 at 18:52
• Define doesn't work. What happens? How does that compare with what you expect? – Delta_G Jun 4 '17 at 18:54
• That may not be the only logical flaw in your program. It's just the one that jumped out at me first. – Delta_G Jun 4 '17 at 18:55
• The calculator spits out 64 no matter the input – Daniel Hendrix Jun 4 '17 at 18:55
• Interesting. 64 is the ascii code for '@'. If you press something that is not % or @ then you're not storing anything. But when you get @ then the first if isn't true and it goes to one of the else if where count is whatever and stores the 64 in one of the spots. – Delta_G Jun 4 '17 at 20:10