Arduino uno + Keypad = calculator

Hey.

I need some help on how i shall beging the code for an easy calculator that can do +, - , *, /.
That will show result in serial monitor.

The code I have now:

#include <Keypad.h>

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

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

//float a = key;
//float b = key;
//float h;
void setup(){
Serial.begin(9600);
}

void loop(){
char key = keypad.getKey();

if (key != NO_KEY){
Serial.print(key);

}

}

The thing is that i i do not know how i shall shall continue.
Need help with following things:

  • code for assigning variables so that i can have use bigger numbers then 9( eg.342 = num1) like store them or something.
  • code so i can take the two diffrent numbers i have put in diffrent variables with the Keypad(eg. 123+45)
  • code so i can press = and get result
  • code so i can press c to begin on a new row

Did read something about using FunctionDeclaration but don't get how to use it with keypad.lib.

I'm really new to this but think i can solve it if i atleast can get an exemple of how it would work with addition.
And to thoose i think goggle it. I have and when i find something it is to complex or they don't how code or they use and lcd screen.

Thx for help

Something to give you an idea. Add and subtract with keypad

Thx will take a look at it and se how far it takes me.

I think the basic idea would be that you have a variable holding the current total, and a variable holding the current operator, and a variable holding the value being entered.

Each time a new operator is entered, apply the previous operator to the total and the entered value, save that as the new total, clear the entered value and save the new operator.

Each time a digit is entered, add it to the value being entered. You could achieve that by storing the digits and '.' characters as a string, or by updating a numeric value directly as each character is received. For the latter, I'd use a finite state machine to deal with the decimal point, although perhaps somebody will think of a way to do it without that. You will need to guard against invalid entries such as multiple decimal points, and also constrain the range of values that can be entered (for example by limiting the number of digits).

The built-in float/double classes only use 32-bits and I think you would need more resolution than that for a calculator to be useful. I suggesting storing your values using fixed point integers. You can support up to 64-bit values using the long long int type. If you want to support values bigger than that, I seem to remember seeing a Big Integer class for Arduino.

will see how far this new info takes me but not certain that i get it.
would be awesome with some example code.

Hello again.
Seem like i hade to use an own keypad kode.
the ting is that i i want to use something like

byte myByte; // a variable to store a byte read from the serial 
// buffer
long mySum; // a variable to hold the sum of the numbers read in from
// the serial buffer
int myNum; // a variable to hold the number being read in from the
// serial buffer

void setup() {
  Serial.begin(9600); // begin serial communications
}

void loop() {
 
 mySum = 0;
 myNum = 0;
 
 if (Serial.available()>0) {
  while(Serial.available()>0){ // while bytes remain in the 
  //serial buffer
  
    myByte = Serial.read(); // read in the current byte
  
    // = is ASCII character 61
    // 0-9 are ASCII characters 48 to 57
    // - is ASCII character 45
    // + is ASCII character 43
    // * is ASCII character 42
    // / is ASCII character 47  
    if (myByte == 61) { // equal sign found - could also do 
    /// if(myByte == '=')
      Serial.print('='); delay(5); // need a short delay so the 
      // Serial.print doesn't garbble subsequent calculations
      Serial.println(mySum); delay(5);
    }
    if (myByte >= '0' && myByte <= '9') { // found the first number
      myNum = myByte-48;
      mySum = myNum;
      Serial.print(myNum); delay(5);
    }
    if (myByte == 45) { // found a minus sign
      myByte = Serial.read(); // read in the next byte
      myNum = myByte-48; // since ASCII number have codes of 48 to 
      // 57, this will convert to the decimal equivelent
      Serial.print('-'); delay(5);
      Serial.print(myNum); delay(5);
      mySum = mySum - myNum; // subtract from total
    }
    if (myByte == 43) { // found a plus sign
      myByte = Serial.read(); // read in the next byte
      myNum = myByte-48;
      Serial.print('+'); delay(5);
      Serial.print(myNum); delay(5);;
      mySum = mySum + myNum; // add to total
    }
    
    if (myByte == 42) { // found a multi sign
      myByte = Serial.read(); // read in the next byte
      myNum = myByte-48;
      Serial.print('*'); delay(5);
      Serial.print(myNum); delay(5);;
      mySum = mySum * myNum; // add to total
    }
    
    if (myByte == 47) { // found a div sign
      myByte = Serial.read(); // read in the next byte
      myNum = myByte-48;
      Serial.print('/'); delay(5);
      Serial.print(myNum); delay(5);;
      mySum = mySum / myNum; // add to total
    }
   } 
  }
}

i want to use my code to put in the numbers and make so that i can put in numbers like 999 and so on.

  int buttonPin1 = 12;
    int buttonPin2 = 11;
    int buttonPin4 = 10; 
    int buttonPin10 = 9;
    int buttonPin5 = 7;
    int buttonPin6 = 6;
    int buttonPin7 = 5;
    int buttonPin8 = 4;
    
  
     
void setup() {      
  
Serial.begin(9600);
 
   pinMode(buttonPin5, OUTPUT);  
   pinMode(buttonPin6, OUTPUT);  
   pinMode (buttonPin7, OUTPUT);
   pinMode (buttonPin8, OUTPUT);
   pinMode (buttonPin1, INPUT);
   pinMode (buttonPin2, INPUT);
   pinMode (buttonPin4, INPUT);
   pinMode(buttonPin10, INPUT);
 
}

void loop() {


  digitalWrite(buttonPin5, HIGH);
  digitalWrite(buttonPin6, LOW);
  digitalWrite(buttonPin7, LOW);
  digitalWrite(buttonPin8, LOW);

  
  //Nummer 1
  if (digitalRead (buttonPin1) == HIGH){
      Serial.println("1");
    delay(500);
    }
   
  //Nummer 2
 else if (digitalRead (buttonPin2) == HIGH){ 
      Serial.println("2");
      delay(500);
    }
   //Nummer 3
 else if (digitalRead (buttonPin4) == HIGH){ 
      Serial.println("3");
      delay(500);
    }  
    //Nummer *
 else if (digitalRead (buttonPin10) == HIGH){ 
      Serial.println("*");
      delay(500);
    }
          
 
  
  digitalWrite(buttonPin5, LOW);
  digitalWrite(buttonPin6, HIGH);
  digitalWrite(buttonPin7, LOW);
  digitalWrite(buttonPin8, LOW);
//____________________________________________
  //Nummer 4
  if (digitalRead (buttonPin1) == HIGH){
      Serial.println("4");
      delay(500);
    }
  
  
  //Nummer 5
 else if (digitalRead (buttonPin2) == HIGH ){
      Serial.println("5");
    delay(500);
 }
    //Nummer 6
 else if (digitalRead (buttonPin4) == HIGH){ 
      Serial.println("6");
      delay(500);
    }
 //Nummer +
 else if (digitalRead (buttonPin10) == HIGH){ 
      Serial.println("+");
      delay(500);
    }
    
  digitalWrite(buttonPin5, LOW);
  digitalWrite(buttonPin6, LOW);
  digitalWrite(buttonPin7, HIGH);
  digitalWrite(buttonPin8, LOW);

//Nummer 7
  if (digitalRead (buttonPin1) == HIGH){ 
      Serial.println("7");
      delay(500);
    }
    //Nummer 8
 else if (digitalRead (buttonPin2) == HIGH){ 
      Serial.println("8");
      delay(500);
    }
    //Nummer 9
 else if (digitalRead (buttonPin4) == HIGH){ 
      Serial.println("9");
      delay(500);
    }
 //Nummer 
 else if (digitalRead (buttonPin10) == HIGH){ 
      Serial.println("-");
      delay(500);
    }
    //__________________________________________________
  digitalWrite(buttonPin5, LOW);
  digitalWrite(buttonPin6, LOW);
  digitalWrite(buttonPin7, LOW);
  digitalWrite(buttonPin8, HIGH);
  
  //Nummer *
  if (digitalRead (buttonPin1) == HIGH){ 
      Serial.println("*");
      delay(500);}
  
  //Nummer 0
 else if (digitalRead (buttonPin2) == HIGH){ 
      Serial.println("0");
      delay(500);}
  
  //Nummer #
 else if (digitalRead (buttonPin4) == HIGH){ 
      Serial.println("#");
      delay(500);
    }
    
 //Nummer /
 else if (digitalRead (buttonPin10) == HIGH){ 
      Serial.println("/");
      delay(500);
    }
    
    int nr1 = 0;
    nr1 = Serial.read();
    nr1 = nr1 & 0x0f;
    
    if ("#"){
      Serial.println(nr1);}
    //int nr2 = 0:
}
  
    }

I think i need to make some kinde of arry or something. But do not know how.

I made a keypad calculator last night, I would suggest you start with using the keypad library, it will make things so much easier.

As for inputting numbers greater than 9:
If you look at it the right way, it is surprisingly simple.

Note that:

25 = (2 * 10) + 5
49 = (4 * 10) + 9
70 = (7 * 10) + 0
386 = (((3 * 10) + 8) * 10) + 6
2051 = (((((2 * 10) + 0) * 10) + 5) * 10) + 1

Algorithm:

Let n equal 0.
Each time you press a digit, change n to (n * 10) + d where d is the new digit.
As for limiting the total number of digits:
For example, if maximum is 6 digits, then allow input of digits only if n < 100000.

You can also put the emphasis on parsing the input string by storing all the string in one buffer and parsing it. Then you just need the keypad to input the strings. YOu will also need at least "( ) ." back space etc. I would turn to multitap to enter all these and find a parsing code online to do the pasing and calculating. Then try to understand how a string is parsesd into numbers and operations.

I use char arrays and everytime I entered a key, it would shift the array and add the new char. Then once I press +,-,*,/ it would convert the char array to an int. (I made it an int just to test it) If the code see any of the operators, it will go to another code and get the second set of numbers. The code also looks for '=', and if that key is pressed, it gives the result.

You can avoid using strings and string buffers if you make in an RPN calculator. See:
http://www.hpmuseum.org/rpn.htm
You will also not need an = key. However, you will need an ENTER key.

Also, remember to think of this: what happens if I try to divide by zero?

Bear in mind that Arduino floating point precision is based on a 16 bit format, so is only good for about 6 - 7 digits. You will get pretty sloppy results if you intend to use this for any scientific work.

jrdoner:
Bear in mind that Arduino floating point precision is based on a 16 bit format, so is only good for about 6 - 7 digits. You will get pretty sloppy results if you intend to use this for any scientific work.

Not 16 bit. 32 bit. What do you know about scientific work?

You don't need to limit yourself to a native datatype.

You could instead use an array with one element per digit, and use this technique:

I know the video only shows how to add, but you can build up other operations from addition.
For example, multiplication:
75 * 24 can be computed as 750 + 750 + 75 + 75 + 75 + 75

This way, you can deal with very large numbers.

You can then write code to keep track of the position of the decimal point.

Here is a little snippet. Note this a basic way to do it, it can be compressed a little further.

if(customKey != '+' && customKey != '-' && customKey != '*' && customKey != '/' && customKey != 'C') {
      Fnumber[first] = customKey;
      lcd.setCursor(first,0);
      lcd.print(Fnumber[first]);
      first++;
    }
    else firstNum = atol(Fnumber);

    if(customKey == '+'){
      lcd.setCursor(0,1);
      lcd.print("+");
      while(customKey != '='){
        customKey = customKeypad.getKey();
        if (customKey && customKey != '='){
          Snumber[second] = customKey ;
          lcd.setCursor(second,2);
          lcd.print(Snumber[second]);
          second++;
        }
      }
      secondNum = atol(Snumber);
      total = firstNum + secondNum;
      lcd.setCursor(0,3);
      lcd.print(total);
      clearData();
    } 

//=====OUT SIDE OF LOOP===
void clearData(){
  while(first != 0){
    Fnumber[first] = 0;
    first--;
  }
  while(second != 0){
    Snumber[second] = 0;
    second--;
  }
  return;
}