Как сверить комбинацию клавиш с массивом

Здравствуйте! Есть массив с номерами кнопок (5 шт) в случайном порядке к примеру 2, 1, 4, 3, 5 , нужно проверять последовательность нажатий кнопок чтобы комбинация сошлась, и тогда получить подтверждение, иначе при первой неправильной кнопке ошибка. Подскажите пожалуйста примерно как решить.

А как бы лично Вы решали эту задачу, если бы она стояла непосредственно перед Вами?
Напишите последовательность своих действий в этом случае.
Точно так же должен работать и контроллер.

1 лайк

ТС, набери в гуголе “Кодовый замок Arduino” и читай до просветления

Записать введенные номера кнопок в массив и сверять последовательно - сначала первые, потом вторые, потом третьи… Если все пять пар совпадают - значит код верный.

#include <Button.h>

#define LED_1 2    // пины светодиодов
#define LED_2 3
#define LED_3 4
#define LED_4 5
#define LED_5 6

#define BUT_1 7    // пины кнопок
#define BUT_2 8
#define BUT_3 9
#define BUT_4 10
#define BUT_5 11

#define RELAY 12   // пин реле

#define NUM_KEYS 7 // количество знаков в коде

Button butt_1(BUT_1, 15); // обьекты кнопок
Button butt_2(BUT_2, 15);
Button butt_3(BUT_3, 15);
Button butt_4(BUT_4, 15);
Button butt_5(BUT_5, 15);

byte combine[NUM_KEYS] = {3, 1, 4, 2, 1, 5, 3}; // заданная комбинация
byte button_pressed[NUM_KEYS];                  // массив хранящий номера нажатых кнопок
uint8_t pressedCounter = 0;                     // счетчик нажатий
byte mode = 0;                                  // 0 - старт, 1 - ожидание ввода, 2 - успешный ввод  
uint32_t timer;                                 // таймер счетчик
#define PERIOD 1000                             // время задержки миганий

void setup()
{
  pinMode(LED_1, OUTPUT);      // светодиоды пины выход
  pinMode(LED_2, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_4, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(RELAY, OUTPUT);      // реле пин выход
  digitalWrite(RELAY, 0);      // реле по умолчанию ВЫКЛ
  Serial.begin(9600);
}

void loop()
{
  if (mode == 0)               // ЕСЛИ ГОТОВНОСТЬ == 0 (мигания)
  {
    for (byte e = 0; e < sizeof(button_pressed); e++) // сброс массива нажатий кнопок
    {
      button_pressed[e] = 0;
    }
  	for (byte a = 0; a < 3; a++) // выполнить 3 раза
  	{
  	  for (byte b = 2; b < 6; b++) // выбрать все
  	  { digitalWrite (b, 1); }     // вкл светодиоды
  	  delay(PERIOD);               // пауза
  	  for (byte b = 2; b < 6; b++) // выбрать все
  	  { digitalWrite (b, 0); }     // выкл светодиоды
  	  delay(PERIOD);               // пауза
  	}
    for (byte c = 0; c < NUM_KEYS; c++) // мигает комбинация с массива
    {
    	digitalWrite(combine[c] + 2, 1);
    	delay(PERIOD);
      digitalWrite(combine[c] + 2, 0);
    }
    mode = 1;
  }

  else if (mode == 1) // ЕСЛИ ГОТОВНОСТЬ == 1 (ожидание ввода)
  {
  //---------- Опрос кнопок ----------

   butt_1.scanState();
   butt_2.scanState();
   butt_3.scanState();
   butt_4.scanState();
   butt_5.scanState();

  //---------- Если любая кнопка нажата, отпределяем какая записываем в массив ----------

   if (press())                                                     // проверка на нажатие
   {
     uint8_t numButt;
     if      (butt_1.flagPress == 1) numButt = 1;
     else if (butt_2.flagPress == 1) numButt = 2;
     else if (butt_3.flagPress == 1) numButt = 3;
     else if (butt_4.flagPress == 1) numButt = 4;
     else if (butt_5.flagPress == 1) numButt = 5;
     button_pressed[pressedCounter] = numButt;                      // запись в массив

     if (button_pressed[pressedCounter] == combine[pressedCounter]) // если прав кнопка
     {
     	 digitalWrite(pressedCounter + 1, 0);                         // предыдущий светодиод гасим
     	 digitalWrite(pressedCounter + 2, 1);                         // текущий светодиод горит
                                                   ]
     }
     else if (!button_pressed[pressedCounter] == combine[pressedCounter]) // если не прав кнопка
     {
     	 mode = 0;                                              // сброс игры
       pressedCounter = 0;                                         // сброс счетчика елементов массива нажатий
     }
     if (pressedCounter == NUM_KEYS)
     {
       correctInput(); // если все ячейки заполнены
       mode = 2;
     } 
     else pressedCounter++;          // иначе для следующего нажатия переходим к новой ячейке

   } 

  }
  else if (mode == 2)
  {

  }
  Serial.println(mode);
}

bool press()
{
    bool flag;
    if      (butt_1.flagPress == 1) flag = 1;
    else if (butt_2.flagPress == 1) flag = 1;
    else if (butt_3.flagPress == 1) flag = 1;
    else if (butt_4.flagPress == 1) flag = 1;
    else if (butt_5.flagPress == 1) flag = 1;
    else flag = 0;
    return flag; 
}

void correctInput()
{
  for (byte a = 0; a < 5; a++) // выполнить 5 раз
  	{
  	  for (byte b = 2; b < 6; b++) // выбрать все
  	  { digitalWrite (b, 1); }     // вкл светодиоды
  	  delay(PERIOD);               // пауза
  	  for (byte b = 2; b < 6; b++) // выбрать все
  	  { digitalWrite (b, 0); }     // выкл светодиоды
  	  delay(PERIOD);               // пауза
  	}
    digitalWrite(RELAY, 1);
}

Не хватает понимания логики перевода в языковую конструкцию, не работает

Посмотрел

Какие ошибки вижу сразу

  1. При переходе от mode=0 к mode=1 счетчик нажатий pressedCounter не обнуляется

  2. Вот в этом куске какой светодиод вы будете гасить при первом нажатии?

  1. Это условие не сработает при нажатии последней кнопки
  1. Этот цикл не делает то, что написано в комменте - то есть не выбирает все светодиоды:

В целом, обратите внимание на индексы в массиве.
Массивы в С начинаются нуля, поэтому число элементов массива, например, 5, но индексы элементов 0…4. У вас с этим постоянная путаница

И еще - советую и кнопки и светодиоды огранизовать в массивы - код станет проще и понятнее

Добавка.
Не знаю, что там внутри класса Button.h , что вы используете, но надеюсь оно умеет отслеживать смену состояния кнопки и взводит flagPress только один раз при каждом нажатии.