Не могу заставить мой калькулятор работать

Вчера я купил себе arduino uno. Поскольку я довольно новичок в этом, я хотел бы попросить здесь подсказку, потому что мне не удается заставить мой "калькулятор" работать. У меня нет большого опыта в программировании, но я подумал, что цикл должен дождаться завершения одной из вызываемых функций, вместо этого, похоже, он снова запускает все функции, и, вероятно, именно поэтому я получаю ошибку в выводе на консоль.

Код:

  #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);
}

Что я хотел сделать, так это дважды прочитать цифровой ввод с клавиатуры (это только на данный момент. Я знаю, что это должно быть сделано по-другому), а затем введите операцию, такую как умножение, но поскольку цикл вызывает функцию снова и снова, я не могу этого сделать. Как я должен подойти к этому?

, 👍1

Обсуждение

включите флаг ... valueValid ... установите его после завершения расчета ... очистите его после печати значения, @jsotola


1 ответ


2

Рассмотрим этот отрывок из вашего кода:

int getNumber() {
    char user_input = keys.getKey();
    int value;
    if (user_input) {
        // ...
    }
    return value;
}

Подумайте о том, что произойдет, если условие if (user_input) окажется ложным. Функция просто вернет неинициализированную переменную, которая содержит в основном мусор.

Метод getKey() из библиотеки клавиатуры намеренно неблокирующий. Он возвращается немедленно, чтобы избежать зависания остальной части вашей программы в ожидании ввода с клавиатуры. Если нажата какая -либо клавиша, метод возвращает эту клавишу. В противном случае он возвращает NO_KEY, который равен нулю и, как логическое значение, принимает значение false. Это означает, что, когда ни одна клавиша не нажата, функция getNumber() возвращается немедленно, и она возвращает мусор.

Правильный подход, вероятно, включал бы какой-то конечный автомат. Однако для этого простого примера вам может сойти с рук быстрое и грязное решение: блокировать во время ожидания ввода пользователем:

// Дождитесь ввода данных пользователем.
do {
    user_input = keys.getKey();
} while (!user_input);

Имейте в виду, однако, что, если ваша программа будет развиваться, в какой -то момент блокирующий подход может стать проблемой, и вам, возможно, придется полностью переписать логику неблокирующим способом.

,