Скрипт должен ждать второго нажатия кнопки

СергМен

✩✩✩✩✩✩✩
16 Мар 2021
2
0
Доброго времени суток, уважаемые форумчане. Прошу помощи с решением задачи.
Алгоритм скрипта ниже задумывался таким:
1. на проходе цикла n-раз, сгенерировать переменную.
1.1 поместить ее в массив
1.2 подать высокий сигнал на соответствующий пин.
2. считать нажатие кнопки
2.1 если номер кнопки соответствует цифре в массиве, увеличить n на 1 и т.д.
2.2 если n больше 2, после нажатия 1й кнопки и верного сравнения с записью в массиве, ждать нажатие второй кнопки и сравнить её с соответствующей ячейкой в массиве, после чего увеличить n на 1.
На деле выходит, что после первого нажатия кнопки, скрипт не ждет второго нажатия а сразу считает что была нажата эта же кнопка, что автоматически сбрасывает n на 1
в Wokwi скрипт работает как надо, там и писался, на плате, увы нет.
C++:
int lastButton = 0;
int key() {
  int val = analogRead(5);
  if (val != lastButton) {
    delay(10);  // Ждем пока состояние стабилизируется - игнорируем дребезг
    int val = analogRead(5);
  }
  if (val < 50) return 3;
  else if (val < 513) return 4;
  else if (val < 683) return 5;
  else if (val < 768) return 6;
  else if (val < 819) return 7;
  else if (val < 853) return 8;
  else if (val < 878) return 9;
  else if (val < 896) return 10;
  else if (val < 910) return 11;
  else if (val < 922) return 12;
  else if (val < 931) return 13;
  else if (val < 939) return 14;
  else return 0;
}  //int key()
int r, c, n, i, j, q, w, u, l, t, ww;
int arr[50];
long randNumber;
int game2() {
labelNO:
  for (q = 0; q < 10; q++) {  // Цикл1 Большой цикл
    n++;
    t = t - ((t / 100) * 5);  // t + 5%
    Serial.print("----------");
    Serial.print("n:");
    Serial.println(n);
    for (i = 0; i < n; i++) {  // Цикл2 Малый цикл
label:
      randNumber = random(3, 14);
      if (r == randNumber) {
        goto label;
      }
      r = randNumber;
      arr[i] = randNumber;
      digitalWrite(randNumber, HIGH);
      delay(t);
      digitalWrite(randNumber, LOW);
      Serial.print("randNumber:");
      Serial.println(randNumber);
    }
label2:
    for (w = 0; w < n; w++) {
      int k = arr[w];
      for (ww = 0; ww < 55555; ww++) {  // Цикл таймер
        if (k == key()) {
          Serial.println("OK");
          Serial.print("arr[w]: ");
          Serial.println(k);
          Serial.print("key(): ");
          Serial.println(key());
          digitalWrite(key(), HIGH);
          delay(50);
          digitalWrite(key(), LOW);
          break;
        } else if (key() != 0 && k != key()) {
          Serial.println("NO");
          Serial.print("arr[w]: ");
          Serial.println(k);
          Serial.print("key(): ");
          Serial.println(key());
          digitalWrite(key(), HIGH);
          delay(50);
          digitalWrite(key(), LOW);
          Serial.println(analogRead(0));
          n = 0;
          goto labelNO;
        }
      }  //for (ww
    }    //for (w
  }      //Цикл1 Большой цикл
}

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(17));
  n = 0;
  t = 500;
}
void loop() {
  game2();
}  //void loop()
 

bort707

★★★★★★✩
21 Сен 2020
2,926
876
Вот это вот - не антидребезг, а полная фигня.
C++:
if (val != lastButton) { 
  delay(10); // Ждем пока состояние стабилизируется - игнорируем дребезг
  int val = analogRead(5);
 }
Во-первых, оно не предотвращает чтение одной и той же кнопки несколько раз подряд(из-за чего у вас проблемы в коде)
А во-вторых, если кнопка сменилась - этот код ее не будет читать, пока не вылезет прежнее значение
 

VAF

✩✩✩✩✩✩✩
15 Июл 2023
24
0
Москва
Не увидел присвоение lastButton значения после нажатия на кнопку первый раз.
 

СергМен

✩✩✩✩✩✩✩
16 Мар 2021
2
0
@bort707,
"Во-первых, оно не предотвращает чтение одной и той же кнопки несколько раз подряд" - расскажите об этом подробнее пожалуйста или хотя бы ключи для поиска в Гугл накидайте плиз
"пока не вылезет прежнее значение" - это тоже
 

VAF

✩✩✩✩✩✩✩
15 Июл 2023
24
0
Москва
Проблема второго чтения кнопки при первом нажатии решается установкой паузы delay() или отслеживанием времени назначается переменная last, которой присваивается значение last=millis() при нажатии, а затем только if(millis()-last> задержки) можно проверять кнопку.
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
19
1
Ну смотри...

Во-первых СергМен, тебе дяди с большими ушами не объясняли, что не нужно без самой крайней надобности использовать безусловны переход GOTO?
Если немного подумать,в 99% случаев можно обойтись без него.

Далее... Командой AnalogRead ты считываешь с 5 пина с помощью Аналагово-Цифрового преобразователя некоторое значение напряжения на данном пине.
Я сперва подумал у тебя там какой-то тензо датчик и типа от силы нажатия, делается return 6,7 и пр.
Если у тебя там тупо кнопка на 5 пине, то у тебя будет прилетать стабильно 1023

ватыкни в код, даже в пустой. Serial.println(analogRead(5)); и убедись в этом.

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

Либо используй уже готовые решения.
 
Изменено: