Не работает код для игры "Повтори мелодию"?

maxet
Offline
Зарегистрирован: 30.06.2018

Да, да, да я украл идею у Alexgyver, но захотел сам его сделать. Кто не знает что это, смысл такой : генерируется пять сигналов пищалки с 4 случайными промежутками, а потом ты должен повторить эту последовательность кнопкой. Вроде звучит просто, но мне, как новичку, эта задача заняла много времени, но всё роавно не заработала.

int last_time[5] = {0, 0, 0, 0, 0}; // создаю 5 переменных, запоминающих време после включения (миллис)
void setup() {
  // put your setup code here, to run once:
     randomSeed(analogRead(0)); // беру рандомное значение с аналогового пина 0
     Serial.begin(9600); 
     pinMode(3, INPUT_PULLUP);// подключаю кнопку

}

void loop() {
  // put your main code here, to run repeatedly:
  int tim[] = {random(100, 1000), random(100, 1000), random(100, 1000), random(100, 1000)}; // создаю 4 рандомных промежутка между нажатиями
  for (int i = 0; i < 5; i++) { // пищалка пищит 5 раз
    tone(5, 1000, 70);
    if (i != 4) {delay(tim[i]); } // делаю промежутки после сигналов кроме последнего(после него не нужно)
  }
  while(1) { //жду первое нажатие
      if (!digitalRead(3)) {
        last_time[0] = millis();  // запоминаю время, когда произошло первое нажатие
        delay(100); // во избежании дребезга 100 милисекунд жду
        break; // заканчиваю ожидание если кнопка нажалась
      }
  }
  
  for (int i = 0; i < 4; i++) { // четыре раза жду нажатий
   
    while(1) {
      if (!digitalRead(3) && tim[i] - 2000 < millis() - last_time[i] && tim[i] + 2000 > millis() - last_time[i]) { // когда кнопка нажата И отставание от промежутка не превышает 2 секунд И "передержание" промежутка не ниже 2 секунд 
        last_time[i + 1] = millis(); // запоминаю время от включения НО так как 0 уже занят то на одно больше
                delay(100); // избежание дребезга
        break; // заканчиваю цикл
          }
      }    
    }
     
    
 tone(5, 5000, 500); // звук победы
  delay(5000);
}

при запуске данного кода даётся пять сигналов, но сколько бы я не нажимал никогда не звучит сигнал победы, даже учитывая то, что "радиус ошибок" равен 2 секундам!.  Буду рад любой идее!

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А как же муки творчества, бессонные ночи, кучи экспериментов? Уберите рандом и задайте жесткие значения, проверьте. Уберите странные, на мой взгляд, конструкции и замените на что-нибудь удобоваримое:

while(digitalRead(3)) ; //жду первое нажатие
        last_time[0] = millis();  // запоминаю время, когда произошло первое нажатие
        delay(100); // во избежании дребезга 100 милисекунд жду

 

maxet
Offline
Зарегистрирован: 30.06.2018

Спасибо

maxet
Offline
Зарегистрирован: 30.06.2018

Кстати кучи эксперементов были(в порте вывода)

maxet
Offline
Зарегистрирован: 30.06.2018

Я уже близок к победе, НО

int last_time[5] = {0, 0, 0, 0, 0};                     // создаю 5 переменных, запоминающих време после включения (миллис)
void setup() {
  // put your setup code here, to run once:
     randomSeed(analogRead(0));                      // беру рандомное значение с аналогового пина 0
     Serial.begin(9600); 
     pinMode(3, INPUT_PULLUP);                                         // подключаю кнопку

}

void loop() {
  // put your main code here, to run repeatedly:
  int tim[] = {700, 700, 700, 700};                            // создаю 4 рандомных промежутка между нажатиями
  for (int i = 0; i < 5; i++) {                                // пищалка пищит 5 раз
    tone(5, 1000, 70);
    if (i != 4) {delay(tim[i]); }                          // делаю промежутки после сигналов кроме последнего(после него не нужно)
  }
  while(digitalRead(3)) {                                 //жду первое нажатие
        last_time[0] = millis();                                // запоминаю время, когда произошло первое нажатие
                                                   // во избежании дребезга 100 милисекунд жду    
  }
  Serial.println("Есть."); 
  delay(100);  
  
  for (int i = 0; i < 4; i++) { // четыре раза жду нажатий
    
   
    while(1) {
      
      if (!digitalRead(3)) { 
      Serial.println("Кнопка нажата.");
       Serial.println(millis() - last_time[i]);   
                  if (tim[i] - 2000 < millis() - last_time[i]) {
                  Serial.println("Одно условие есть.");  
          
                            if ( tim[i] + 2000 > millis() - last_time[i]) {
        
                               Serial.println("Условие выполненно.");                                                                         
                                last_time[i + 1] = millis();                                                                                                                                                                                                         
                                break;
                               }                                                                                                       
                      }
      delay(100);
      }
    }
      }       
     
 tone(5, 5000, 500);                                            // звук победы
  delay(5000);
}

Обратите внимание на 27 - 44 строку . Я для ясности разбил условие на три части, чтоб понять в чём проблемма. При каждом нажатии у меня выводится это (число конечно же меняется)

13:08:30.116 -> Кнопка нажата.
13:08:30.151 -> 688
 
и так до бесконечности, а " Одно условие есть" не выводится. Причём можно проверить условие.
tim[i] - 2000 < millis() - last_time[i]
это
700 - 2000 < 688 
В принципе это должно возвращать истину, но почему- то это не так. В чё проблемма?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

maxet пишет:

Да, да, да я украл идею у Alexgyver, но захотел сам его сделать. 

Кто или что мешает? Делайте сами. Сюда-то зачем пришли?

Если уж сами никак, так топайте на адекватный такому проекту форум - https://community.alexgyver.ru/

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый ТС - поучите немного Си и научитесь хотя-бы копировать правильно. То, что у Вас в 17 строке никак не похоже на то, что Вам написал я. Кроме того то же самое надо сделать в 26 строке. И вообще - привести программу к читабельному виду, а не как у Гайвера - широкими мазками и нихрена сам даже не понимает чего пишет. А уж повторить...

maxet
Offline
Зарегистрирован: 30.06.2018

 

О, милейший, надеюсь так вашим глазам будет лучше, ибо данный говносайт(как оказалось) не умещает такие коды.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

maxet пишет:

О, милейший, надеюсь так вашим глазам будет лучше, ибо данный говносайт(как оказалось) не умещает такие коды.

О, как всё запущено ... ты ещё и права покачать решил.

Значит так, родной, вариантов у тебя два: или к отцу родному и богу всемогущему, или *************

Сам выбирай, подсказывать не буду.

leks
Offline
Зарегистрирован: 22.10.2017

А вообще не странно присваивать элементам массива значения функции миллис? У одних int, у других long?

maxet
Offline
Зарегистрирован: 30.06.2018

Или что?

leks
Offline
Зарегистрирован: 22.10.2017

maxet пишет:

Или что?

Не в ту тему послал сообщение... Где Гайвер пишет такое ?- int time[0]=millis();

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

leks пишет:

Где Гайвер пишет такое ?- int time[0]=millis();

Он только так и пишет. Вот тут как раз и на эту тему с ним срач был - http://arduino.ru/forum/programmirovanie/neskolko-interesnykh-i-poleznykh-bibliotek

leks
Offline
Зарегистрирован: 22.10.2017

ЕвгенийП пишет:

leks пишет:

Где Гайвер пишет такое ?- int time[0]=millis();

Он только так и пишет. Вот тут как раз и на эту тему с ним срач был - http://arduino.ru/forum/programmirovanie/neskolko-interesnykh-i-poleznykh-bibliotek

Получается не очень скетч через минуту работать будет у ТС.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

leks пишет:

Получается не очень скетч через минуту работать будет у ТС.

Так вот, жертва гайвера и удивляется "всё делал по инструкции" :(