Оператор Switch застрял в цикле

lcd switch keypad

Я пишу код, чтобы пользователь мог ввести 4-значный пин-код, а затем использовать этот пин-код для разблокировки ящика. Цикл застрял между полем «готов к разблокировке» и «введите пин-код», он просто продолжает переключаться между значениями, но я хочу, чтобы оба отображались, просто в разное время.

#include <Keypad.h> //установить библиотеку клавиатуры
#include <LiquidCrystal.h> //установить библиотеку ЖК-экранов

const byte ROWS = 4; //включить четыре ряда клавиатуры
const byte COLS = 4; // включаем четыре столбца клавиатуры

char keys[ROWS][COLS] = { //установить массив клавиатуры равным числам на клавиатуре
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

int pin1, pin2, pin3, pin4, pin5, pin6, pin7, pin8;
int code[] = {pin1, pin2, pin3, pin4};

byte rowPins[ROWS] = {45,43,41,39}; // подключаемся к ряду контактов клавиатуры
byte colPins[COLS] = {37,35,33,31}; //подключение к контактам колонки клавиатуры

LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // устанавливаем контакты, к которым будет подключен ЖК-дисплей
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // устанавливаем клавиатуру для использования в качестве переменной

int solenoidPin = 1; // подключаем вывод мотора к коду

bool in_press = false;
void setup() {
   Serial.begin(9600); //стартовый код
   lcd.begin(16,2); //стартовый экран с размерами
}

void loop() // цикл функций для выполнения
{ 
  int key; //инициализировать ключ как целое число

  lcd.setCursor(0,0);
  lcd.print("Press # to lock,");//экран приветствия
  lcd.setCursor(0,1);
  lcd.print("or * to unlock.");

  key = keypad.getKey(); // сообщаем arduino, что ждем значения

    while (in_press && key == NO_KEY) //проверить, хотят ли они начать
    { 
      in_press = false; //если ни одна клавиша не была нажата
      return; //выходим из цикла и перезагружаемся
    }

    while (key != NO_KEY){ //если была нажата клавиша
      switch(key){
      case '#':
        lcd.clear();
        lcd.setCursor(0,0);
        *lcd.print("Ready to lock"); // сообщаем пользователю о готовности к следующему шагу процесса
        lcd.setCursor(0,1);
        lcd.print("keys!");
        delay(1000);
        EnterPin1();
        break;*

      case '*':
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Ready to unlock"); // сообщаем пользователю о готовности к следующему шагу процесса
        lcd.setCursor(0,1);
        lcd.print("keys!");
        delay(1000);
        EnterPin5();
        break;

       default:
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("No input");
       lcd.setCursor(0,1);
       lcd.print("detected.");
       break;
  }
 }
}

void EnterPin1()
{
  Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
  bool in_press = false;
  int pin1;

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Enter your pin.");//сообщите пользователю, что вы ждете ввода
  delay(1000);

  pin1 = keypad.getKey(); // сообщаем arduino, что ждем значения

    while (in_press && pin1 == NO_KEY) //проверить, хотят ли они начать
    { 
      in_press = false; //если ни одна клавиша не была нажата
      return; //выходим из цикла и перезагружаемся
    }

    while (pin1 != NO_KEY) //если была нажата клавиша
    { 
      switch(pin1){
      case '1':
        pin1 = 1;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*"); // сообщаем пользователю о готовности к следующему шагу процесса
        EnterPin2(); // переходим к вводу функции вывода
        break;

      case'2':
        pin1 = 2;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*"); // сообщаем пользователю о готовности к следующему шагу процесса
        delay(1000);
        EnterPin2();
        break;

      case '3':        
        pin1 = 3;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '4':
        pin1 = 4;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '5':
        pin1 = 5;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '6':
        pin1 = 6;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '7':
        pin1 = 7;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");    
        EnterPin2();
        break;

      case '8':
        pin1 = 8;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;

      case '9':
        pin1 = 9;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*");
        EnterPin2();
        break;
   }
  }
 } 

, 👍0

Обсуждение

Логика может быть неправильной. Также попробуйте создать https://en.wikipedia.org/wiki/Finite-state_machine, чтобы избежать необходимости определять несколько функций EnterPin1, EnterPin2 3 и т. д., @MichaelT


1 ответ


1

Ваш основной код цикла устанавливает key, а затем имеет цикл while (key != nokey) {} после, но значение ключа никогда не изменяется внутри while петля. Таким образом, если ключ не равен noKey, цикл while никогда не завершится.

key = keypad.getKey();

while (key != noKey) {
  //код, который не меняет ключ
}

Это бесконечный цикл. Тот факт, что внутри цикла while есть оператор switch, не имеет значения. Ни один из этих кодов не изменяет значение key, поэтому цикл никогда не завершится.

Вместо этого напишите так:

key = keypad.getKey();
while (key != noKey) {
  //Ваш текущий код
  key = keypad.getKey();
}

У вас та же логическая проблема в функции enterPin1. Вы не предоставляете код для своей функции enterPin2, но я предполагаю, что она также имеет ту же логическую проблему.

,

Это дает мне ошибку «ожидается ')' перед ';' token», есть ли еще одна часть, которую я должен добавить туда?, @Nicole

Хорошо, я не был уверен, является ли этот синтаксис законным или нет. Очевидно нет. Я на планшете, где у меня нет доступа к компилятору C. Вы можете использовать свой код, но добавьте key = kaypad.getKey() в качестве последнего оператора в цикле while, чтобы получить другое значение для ключа перед повторным циклом., @Duncan C

Смотрите редактирование моего ответа. Есть более элегантный способ сделать это, но в данный момент у меня нет доступа к компилятору, чтобы сделать это правильно для вас., @Duncan C