Игра на память ардуино

Итак, у меня есть проект, который заключается в создании простой игры на память с использованием Arduino, где светодиоды должны мигать по определенному шаблону, а игрок должен имитировать тот же шаблон. но, к сожалению, у меня такие проблемы с кодом Я хочу сделать оператор if, чтобы проверить, была ли нажата кнопка или нет, если да, то он продолжает проверять вторую кнопку, и если это не был красный светодиод (что означает неправильно), должен включиться вот как я начал:

enter code here


const int button1 = 2;          // 1-я кнопка управляет синим светодиодом
const int button2 = 3;          // 2-я кнопка управляет желтым светодиодом
const int button3 = 4;          // 3-я кнопка управляет зеленым светодиодом
const int button4 = 5;          // 4-я кнопка управляет красным светодиодом
const int led1 = 7;             // Синий светодиод
const int led2 = 8;             // Желтый светодиод
const int led3 = 9;             // Зеленый светодиод
const int led4 = 10;            // Красный светодиод
const int correctLED = 6;
const int wrongLED = 11;
int val = 0;

// Переменные
int buttonState[] = {0,0,0,0};         // текущее состояние кнопки
int lastButtonState[] = {0,0,0,0};     // предыдущее состояние кнопки
int buttonPushCounter[] = {0,0,0,0}; 



void setup() {
  // инициализируем входные данные:
  randomSeed(analogRead(0));
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);

  // инициализируем выходы:
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  // инициализируем последовательную связь для отладки:
  Serial.begin(9600); 
        }
  }

 void loop() {
       digitalWrite(7, HIGH);
       digitalWrite(8, HIGH);
       digitalWrite(9, HIGH);
       digitalWrite(10, HIGH);
       digitalWrite(7, LOW);
       digitalWrite(8, LOW);
       digitalWrite(9, LOW);
       digitalWrite(10, LOW);

       digitalWrite(7, HIGH);
       delay(500);
       digitalWrite(7,LOW);
       delay(500);
       digitalWrite(8, HIGH);
       delay(500);
       digitalWrite(8,LOW);
       delay(500);
       digitalWrite(9, HIGH);
       delay(500);
       digitalWrite(9,LOW);
       delay(500);
       digitalWrite(10, HIGH);
       delay(500);
       digitalWrite(10,LOW);
       delay(500);


       val = digitalRead(2);  // читаем входное значение
       if (val == HIGH) {         // проверяем, высокий ли входной сигнал (кнопка отпущена)
       digitalWrite(wrongLED, LOW);  // выключаем светодиод
       } else {
       digitalWrite(wrongLED, HIGH);  // включаем светодиод
       }
       val = digitalRead(3);  // читаем входное значение
       if (val == HIGH) {         // проверяем, высокий ли входной сигнал (кнопка отпущена)
       digitalWrite(wrongLED, LOW);  // выключаем светодиод
       } else {
        digitalWrite(wrongLED, HIGH);  // включаем светодиод
       }
       val = digitalRead(4);  // читаем входное значение
         if (val == HIGH) {         // проверяем, высокий ли входной сигнал (кнопка отпущена)
       digitalWrite(wrongLED, LOW);  // выключаем светодиод
       } else {
       digitalWrite(wrongLED, HIGH);  // включаем светодиод
       }
       val = digitalRead(5);  // читаем входное значение
       if (val == HIGH) {         // проверяем, высокий ли входной сигнал (кнопка отпущена)
       digitalWrite(wrongLED, LOW);  // выключаем светодиод
       } else {
         digitalWrite(wrongLED, HIGH);  // включаем светодиод
       }
       digitalWrite(correctLED, HIGH);

       }
       }

, 👍-1

Обсуждение

Сделайте себе одолжение и научитесь правильно делать отступы в коде., @Majenko

Что касается вашей проблемы: подумайте о паролях., @Majenko

Вы можете автоматически отформатировать свой код в Arduino IDE, зайдя в меню «Инструменты» и выбрав «Автоформат»., @sa_leinad

У вас слишком много закрывающих скобок., @sa_leinad

Проголосовали против, потому что вы не сказали, какая у вас проблема., @per1234


3 ответа


2

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

Вам нужно думать о той последовательности нажатий кнопок, которую вы видели до сих пор, а не о том, что происходит прямо сейчас.

Предположим, у вас есть три кнопки. Присвоим каждой из них номер — скажем, это кнопки 1, 2 и 3.

И у вас есть 3 светодиода — назовем их A, B и C.

Итак, вы зажигаете и гасите светодиоды в определенном порядке, скажем BAC, и ожидаете, что кнопки будут нажиматься в том же порядке — 213.

Вы не можете все время проверять «Если нажата 2, то нажата 1, затем нажата 3», потому что, по сути, где вы находитесь в этой последовательности в любой момент времени? Вместо этого вам нужно сказать: «Нажата кнопка. Я запомню этот факт». А потом: "Три кнопки были нажаты? Да. Их номера совпадают?"

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

Самый простой способ сделать это — буквально присвоить кнопкам номера. Когда кнопка нажата, вы присваиваете переменной номер, представляющий эту кнопку. Затем добавьте этот номер в список номеров, которые вы недавно видели. Когда этот список станет нужной длины, вы его сравните. Точно так же, как ввод пароля.

Вы даже можете сравнить то, что у вас есть на данный момент, с частью того, что вы ожидаете отловить неправильные нажатия на раннем этапе.

Предположим, у вас есть ожидаемое значение «213», сохраненное в строке. У вас также есть пустая строка. Когда вы нажимаете кнопку, вы добавляете это число к строке - скажем, вы нажимаете «212», а затем можете добавить и сравнить строку следующим образом:

Button  Input  Expected
2       2      2         Correct
1       21     21        Correct
2       212    213       Incorrect - erase input content
2       2      2         Correct
1       21     21        Correct
3       213    213       Correct - next round please.
,

2

Помимо формата и дополнительных фигурных скобок, в вашем коде есть и другие проблемы, их слишком много, чтобы уместить их в комментарий.

  1. Вы использовали светодиод1, светодиод2 и т. д. в процедуре настройки и использовали числа в функции цикла.

  2. В начале цикла() вы включаете светодиоды вверх, а затем вниз, вы этого не увидите, потому что процессор работает быстрее, чем ваш глаз, вам нужен оператор задержки после последнего максимума и последнего минимума.

  3. Вы можете сделать свой код более элегантным, написав функцию, которая принимает контакт в качестве параметра и переключает высокий, а затем низкий уровень светодиода и вызывает это вместо повторения 4 строк кода.
void togglePin(int pinNumber, int interval)
{ 
   digitalWrite(pin, HIGH);
   delay(interval);
   digitalWrite(pin, LOW);
   delay(interval);
}
  1. Когда дело доходит до чтения значений, у вас есть блоки повторяющегося кода, опять же, это могут быть отдельные функции, которые облегчат чтение и понимание вашего кода.

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

,

1

В вашем коде в том виде, в котором он написан, будут включены как wrongLED, так и correctLED. Он также будет непрерывно показывать последовательность.

Показ последовательности

Чтобы показать последовательность один раз в начале, поместите ее в функцию настройки. Подробнее о функции настройки читайте здесь: http://www.arduino.cc/en/Reference/Setup< /п>

Обнаружение нажатия кнопок

Вы хотите распознавать каждое нажатие кнопок. Для этого вам понадобится код обнаружения границ. В IDE есть встроенный в IDE пример Arduino, а информацию, описывающую функцию, можно найти здесь: http://www.arduino.cc/en/ Учебное пособие/StateChangeDetection
В дополнение к объяснению Arduino вы можете обнаружить либо нарастающий фронт (т. е. переход от LOW к HIGH), либо спадающий фронт (т. е. переход от HIGH к LOW). Лично я предпочитаю использовать следующий код для обнаружения нарастающего фронта:

if ( (lastButtonState == LOW) && (buttonState == HIGH) )

где buttonState будет назначен digitalRead, а lastButtonState запишет значение buttonState в конце функции цикла (т. е. непосредственно перед тем, как она снова прочитает состояния кнопки).

Используя глобальные массивы, вы можете написать:

buttonState[0] = digitalRead(button1);
buttonState[1] = digitalRead(button2);
buttonState[2] = digitalRead(button3);
buttonState[3] = digitalRead(button4);

if ( (lastButtonState[i] == LOW) && (buttonState[i] == HIGH) )

где i — число от 0 до 3. Вы можете использовать цикл for для переключения между 4 доступными кнопками.

Запись нажатий кнопок

Приведенный выше пример StateChangeDetection подсчитывает количество нажатий кнопок. Вместо этого вы хотите записать 4 нажатия кнопок. Для этого создайте глобальную переменную с именем pressNumber. Создайте его с начальным значением 0.

Создайте целочисленный массив из 4 элементов с именем userSequence.

Каждый раз, когда оператор if обнаруживает нарастающий фронт, сохраняйте номер кнопки в userSequence' в позицииpressNumber, а затем увеличивайтеpressNumber`.

Когда pressNumber достигает 4, пользователь ввел свое предположение.

Оценка предположения

Это происходит только после того, как пользователь ввел предположение. Начните с создания логической переменной и присвойте ей значение TRUE. Перебирайте элементы в массиве userSequence и сравнивайте предположения пользователей с правильным ответом. Если пользователь ошибся, установите для логической переменной значение false. В конце включите красный светодиод или зеленый светодиод в зависимости от состояния логической переменной (т.е. если это правда, включите зеленый светодиод, в противном случае включите красный).

Заключительные замечания

  • Как предлагает Мэтт, попробуйте рефакторинг частей кода в функции. Это делает код более читабельным и снижает его сложность.
  • Вы можете использовать переменные для номеров контактов кнопок и светодиодов в функциях digitalWrite и digitalRead. Например:

    digitalRead(button1); digitalWrite(led1);

,