Здравствуйте! Есть массив с номерами кнопок (5 шт) в случайном порядке к примеру 2, 1, 4, 3, 5 , нужно проверять последовательность нажатий кнопок чтобы комбинация сошлась, и тогда получить подтверждение, иначе при первой неправильной кнопке ошибка. Подскажите пожалуйста примерно как решить.
А как бы лично Вы решали эту задачу, если бы она стояла непосредственно перед Вами?
Напишите последовательность своих действий в этом случае.
Точно так же должен работать и контроллер.
ТС, набери в гуголе “Кодовый замок 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);
}
Не хватает понимания логики перевода в языковую конструкцию, не работает
Посмотрел
Какие ошибки вижу сразу
-
При переходе от mode=0 к mode=1 счетчик нажатий
pressedCounter
не обнуляется -
Вот в этом куске какой светодиод вы будете гасить при первом нажатии?
- Это условие не сработает при нажатии последней кнопки
- Этот цикл не делает то, что написано в комменте - то есть не выбирает все светодиоды:
В целом, обратите внимание на индексы в массиве.
Массивы в С начинаются нуля, поэтому число элементов массива, например, 5, но индексы элементов 0…4. У вас с этим постоянная путаница
И еще - советую и кнопки и светодиоды огранизовать в массивы - код станет проще и понятнее
Добавка.
Не знаю, что там внутри класса Button.h , что вы используете, но надеюсь оно умеет отслеживать смену состояния кнопки и взводит flagPress только один раз при каждом нажатии.