user84810: Yesterday, I've got myself an arduino uno. Since I'm pretty newbie in it, I'd like to ask here for a hint, because I can't manage to make my "calculator" working. I don't have much experience in programming, but I thought, the loop should wait for one of the function called to end, instead of it, it looks like it is running all function, over again, and probably that's why I getting error in console output.
Code:
  #include <Key.h>
#include <Keypad.h>

const byte rows = 4;
const byte columns = 4;

char first_number;


char keyboard[rows][columns] = {
    {'1','2','3','+'},
    {'4','5','6','-'},
    {'7','8','9','/'},
    {'C','0','=','*'}
  };

byte  rowsPins[rows] = {9, 8, 7, 6};
byte columnsPins[columns] = {5, 4, 3, 2};


Keypad keys = Keypad(makeKeymap(keyboard), rowsPins, columnsPins, rows, columns);

void setup(){
    Serial.begin(9600);
  }
  
int getNumber(){
    char user_input = keys.getKey();
    int value;

    if (user_input){
    switch (user_input){
          case '0':
            value = 0;
            break;
          case '1':
            value = 1;
            break;
          case '2':
            value = 2;
            break;
          case '3':
            value = 3;
            break;
          case '4':
            value = 4;
            break;
          case '5':
            value = 5;
            break;
          case '6':
            value = 6;
            break;
          case '7':
            value = 7;
            break;
          case '8':
            value = 8;
            break;
          case '9':
            value = 9;
            break;
          default:
            Serial.print("Error int");
    }
  }
  return value;
}

int calculate(int first_number, int second_number){
    char operation = keys.getKey();
    int value;

    switch(operation){
        case '+':
          value = first_number+second_number;
          break;
        case '-':
          value = first_number-second_number;
          break;
        case '*':
          value = first_number*second_number;
          break;
        case '/':
          value = first_number/second_number;
          break;
        default:
          Serial.println("Error cal");
      }
      if (value){
          Serial.println(value);
        }
     return value;
  }
  

void loop(){

  int first_number = getNumber();
  int second_number = getNumber();
  int test = calculate(first_number, second_number);
}

What I wanted to do, is read numeric input from the keypad twice (it's just for now. I know it should be done different), and then, input the operation, such as multiply, but since the loop calling the function all over again, I can't actually do it. How I should approach it?

user7508: Consider this excerpt from your code:
int getNumber() {
    char user_input = keys.getKey();
    int value;
    if (user_input) {
        // ...
    }
    return value;
}

Think about what would happen if the condition if (user_input) turns
out to be false. The function would simply return an uninitialized
variable, which contains basically garbage.
The method getKey() from the Keypad library is intentionally
non-blocking. It returns immediately in order to avoid the rest of
your program being stuck while waiting for keypad input. If some key is
pressed, the method returns that key. Otherwise it returns NO_KEY,
which is zero and, as a boolean, evaluates to false. This means that,
when no key is pressed, the function getNumber() returns immediately,
and it returns garbage.
The correct approach would probably involve some sort of finite state
machine. However, for this simple example you can get away with a
quick-and-dirty solution: block while waiting for user input:
// Wait for user input.
do {
    user_input = keys.getKey();
} while (!user_input);

Keep in mind though that, if your program is going to evolve, at some
point the blocking approach can become an issue, and you may have to
completely rewrite the logic in a non-blocking fashion.

84810: <p>Yesterday, I've got myself an arduino uno. Since I'm pretty newbie in it, I'd like to ask here for a hint, because I can't manage to make my &quot;calculator&quot; working. I don't have much experience in programming, but I thought, the loop should wait for one of the function called to end, instead of it, it looks like it is running all function, over again, and probably that's why I getting error in console output.</p>
<p>Code:</p>
<pre><code>  #include &lt;Key.h&gt;
#include &lt;Keypad.h&gt;

const byte rows = 4;
const byte columns = 4;

char first_number;


char keyboard[rows][columns] = {
    {'1','2','3','+'},
    {'4','5','6','-'},
    {'7','8','9','/'},
    {'C','0','=','*'}
  };

byte  rowsPins[rows] = {9, 8, 7, 6};
byte columnsPins[columns] = {5, 4, 3, 2};


Keypad keys = Keypad(makeKeymap(keyboard), rowsPins, columnsPins, rows, columns);

void setup(){
    Serial.begin(9600);
  }
  
int getNumber(){
    char user_input = keys.getKey();
    int value;

    if (user_input){
    switch (user_input){
          case '0':
            value = 0;
            break;
          case '1':
            value = 1;
            break;
          case '2':
            value = 2;
            break;
          case '3':
            value = 3;
            break;
          case '4':
            value = 4;
            break;
          case '5':
            value = 5;
            break;
          case '6':
            value = 6;
            break;
          case '7':
            value = 7;
            break;
          case '8':
            value = 8;
            break;
          case '9':
            value = 9;
            break;
          default:
            Serial.print(&quot;Error int&quot;);
    }
  }
  return value;
}

int calculate(int first_number, int second_number){
    char operation = keys.getKey();
    int value;

    switch(operation){
        case '+':
          value = first_number+second_number;
          break;
        case '-':
          value = first_number-second_number;
          break;
        case '*':
          value = first_number*second_number;
          break;
        case '/':
          value = first_number/second_number;
          break;
        default:
          Serial.println(&quot;Error cal&quot;);
      }
      if (value){
          Serial.println(value);
        }
     return value;
  }
  

void loop(){

  int first_number = getNumber();
  int second_number = getNumber();
  int test = calculate(first_number, second_number);
}
</code></pre>
<p>What I wanted to do, is read numeric input from the keypad twice (it's just for now. I know it should be done different), and then, input the operation, such as multiply, but since the loop calling the function all over again, I can't actually do it. How I should approach it?</p>
 7508: <p>Consider this excerpt from your code:</p>
<pre class="lang-cpp prettyprint-override"><code>int getNumber() {
    char user_input = keys.getKey();
    int value;
    if (user_input) {
        // ...
    }
    return value;
}
</code></pre>
<p>Think about what would happen if the condition <code>if (user_input)</code> turns
out to be false. The function would simply return an uninitialized
variable, which contains basically garbage.</p>
<p>The method <code>getKey()</code> from the Keypad library is intentionally
<em>non-blocking</em>. It returns immediately in order to avoid the rest of
your program being stuck while waiting for keypad input. If some key is
pressed, the method returns that key. Otherwise it returns <code>NO_KEY</code>,
which is zero and, as a boolean, evaluates to false. This means that,
when no key is pressed, the function <code>getNumber()</code> returns immediately,
and it returns garbage.</p>
<p>The correct approach would probably involve some sort of <a href="https://majenko.co.uk/blog/finite-state-machine" rel="nofollow noreferrer">finite state
machine</a>. However, for this simple example you can get away with a
quick-and-dirty solution: block while waiting for user input:</p>
<pre class="lang-cpp prettyprint-override"><code>// Wait for user input.
do {
    user_input = keys.getKey();
} while (!user_input);
</code></pre>
<p>Keep in mind though that, if your program is going to evolve, at some
point the blocking approach can become an issue, and you may have to
completely rewrite the logic in a non-blocking fashion.</p>
