Помогите пожалуйста с кодом для Ардуино. Запутался..

guliyev34
Offline
Зарегистрирован: 17.03.2015

И так, написал код. Все работает как и должно. Все удовлетворяет. Но! Кроме одного! В середине цикла есть ввод кнопок. Точнее проверяется какую кнопку нажали, и заносится в массив определенное число. Но получается так, что программа не ждет нажатие кнопки, а продолжает работать дальше. В чем может быть причина? Вот код:

int Dead1 = 10; //Если осталась 1 жизнь
int Dead2 = 9; // Если осталост 2 жизни
int Dead3 = 8; // Если осталось 3 жизни

int Knopka1 = 2;
int Knopka2 = 3;
int Knopka3 = 4;

boolean lastK1 = LOW;
boolean lastK2 = LOW;
boolean lastK3 = LOW; 

int Led1= 5;
int Led2= 6;
int Led3= 7;


void setup() {
  Serial.begin (9600);
  
  pinMode (Knopka1 , INPUT);
  pinMode (Knopka2 , INPUT);
  pinMode (Knopka3 , INPUT);
  
  pinMode (Led1 , OUTPUT);
  pinMode (Led2 , OUTPUT);
  pinMode (Led3 , OUTPUT);
  
  pinMode (Dead1 , OUTPUT);
  pinMode (Dead2 , OUTPUT);
  pinMode (Dead3 , OUTPUT);
  
  randomSeed (analogRead(0)); //Чтобы случайные числа не повторялись
  
              }

void loop() {

  int n = 1; //Уровень
  int N = 10; //Максимальное количество уровней
  int Dead = 3; //Начальное количество жизней
  int tempL; 
  int tempL1;
  int tempK;
  int MassivLed[N];
  int MassivKnopok[N];
  
  //Включение индикации жизней
  digitalWrite(Dead3, HIGH);
  digitalWrite(Dead2, HIGH);
  digitalWrite(Dead1, HIGH);
  
   
  while (Dead > 0 && n <= N) //Сама игра до того пока не закончатся жизни
  {   
   delay (2000);
  //Заполняем массив случайным образом для миганий разных светодиодов
  for (int i=0 ; i < n ; i++)
    {
      tempL = random (1, 4);
      
      //Чтобы небыло повторов
      while (tempL == tempL1) 
      {
        tempL = random (1, 4);
      }
      tempL1 = tempL;
    
      if (tempL == 1) 
        {
          MassivLed[i] = Led1;
        }
      else if (tempL == 2) 
        {
          MassivLed[i] = Led2;
        }    
      else 
        {
          MassivLed[i] = Led3;
        } 
    }
    
  //Воспроизводим это мигание на плате
  for (int i=0; i < n; i++)
  {
      digitalWrite(MassivLed[i], HIGH);
      delay(500);
      digitalWrite(MassivLed[i], LOW);
      delay(500);
   }

   //Записываем нажатие кнопок в массив MassivKnopok
   Serial.println (Knopka1);
   Serial.println (Knopka2);
   Serial.println (Knopka3);
   
  for (int i=0; i < n; i++)
  {
          if (digitalRead (Knopka1) == HIGH )
         {
            MassivKnopok[i] = Led1;
            digitalWrite(Led1, HIGH);
            digitalWrite(Led1, LOW);
         } 
         
          else if (digitalRead (Knopka2) == HIGH )
         {
            MassivKnopok[i] = Led2;
            digitalWrite(Led2, HIGH);
            digitalWrite(Led2, LOW);        
         } 
          else if (digitalRead (Knopka3) == HIGH )
         {
            MassivKnopok[i] = Led3;
            digitalWrite(Led3, HIGH);
            digitalWrite(Led3, LOW);        
         }
   }   

    for (int i=0; i < n; i++)
    {
     if (MassivLed[i] != MassivKnopok [i])
      {
        Dead--;
        break;
      }
      else   n++; //увеличиваем уровень
    }
   
   //Проверяем и изменяем индикацию жизни
   if (Dead == 3) 
  {
    digitalWrite(Dead3, HIGH);
    digitalWrite(Dead2, HIGH);
    digitalWrite(Dead1, HIGH);
  }
  else if (Dead == 2) 
  {
    digitalWrite(Dead3, LOW);
    digitalWrite(Dead2, HIGH);
    digitalWrite(Dead1, HIGH);
  }
  else if (Dead == 1) 
  {
    digitalWrite(Dead3, LOW);
    digitalWrite(Dead2, LOW);
    digitalWrite(Dead1, HIGH);
  }  
  else if (Dead == 0) 
  {
    for (int i = 0 ; i < 3 ; i++)
    {
      digitalWrite(Dead3, HIGH);
      digitalWrite(Dead2, HIGH);
      digitalWrite(Dead1, HIGH);
      delay (500);
      digitalWrite(Dead3, LOW);
      digitalWrite(Dead2, LOW);
      digitalWrite(Dead1, LOW);
      delay (500);
    }
  } 
  
  
  }//while  
  } //loop
  

 

dima.karpus
dima.karpus аватар
Offline
Зарегистрирован: 22.02.2015

о боже та здесь просто незнаю я помоч не смогу 

А что ты хоть хочеш зделать

может смогу помоч или сам то же зделаю и найду ошибку 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
guliyev34
Offline
Зарегистрирован: 17.03.2015

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

 for (int i=0; i < n; i++)
098
  {
099
          if (digitalRead (Knopka1) == HIGH )
100
         {
101
            MassivKnopok[i] = Led1;
102
            digitalWrite(Led1, HIGH);
103
            digitalWrite(Led1, LOW);
104
         }
105
          
106
          else if (digitalRead (Knopka2) == HIGH )
107
         {
108
            MassivKnopok[i] = Led2;
109
            digitalWrite(Led2, HIGH);
110
            digitalWrite(Led2, LOW);       
111
         }
112
          else if (digitalRead (Knopka3) == HIGH )
113
         {
114
            MassivKnopok[i] = Led3;
115
            digitalWrite(Led3, HIGH);
116
            digitalWrite(Led3, LOW);       
117
         }
118
   }  

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

как подключены кнопки ? и в чём проявляется ошибка ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

зачем строки 39-46 не в верхней секции ?
зачем строки 49-51 не в секции сетап ?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

"Я написал программу, она работает классно, вот только один кусочек не работает так как я хочу. Текст программы на 50 строк ниже."

Где здесь написано, что делает скетч? Явно - ни где. Как именно не работает - тоже нигде.

Поскольку я не телепат, могу сам задать вопрос, как Вы думаете, увидите ли Вы как моргнет светодиод вот в такой конструкции:

            digitalWrite(Led1, HIGH);
            digitalWrite(Led1, LOW);

Я не поленился, запустил свой скетч и не вижу, как мигает такой светодиод. Вот скетч:

byte led = 13;

void setup() {
  pinMode(led,OUTPUT);
}

void loop() {
  digitalWrite(led,HIGH);
// Если закомментарить, то не видно как моргает:  delay(1000);
  digitalWrite(led,LOW);
  delay(1000);
}

PS Могу предположить, что Вы зажигаете в случайном порядке светодиоды (3 шт), чел должен нажать соответствующие им кнопки, если угадал, то следующий уровень. Между уровнями светим кол-во оставшихся жизней.

Да, не забудьте схему приложить, от подключения кнопок тоже многое зависит. Я бы порекомендовал, сначала омигать светодиодами, отладить индикацию. Затем поиграться с кнопкам, научиться их считывать. А затем объединить это всё в игру. Иначе будет как получилось.

 

guliyev34
Offline
Зарегистрирован: 17.03.2015

39-46 не знаю. Не подумал. Можно было и в setup добавить. На счет 49-51 там  массивы. Если их описывать в самом верху, то в цикле for выдается ошибка: "error: 'MassivKnopok' was not declared in this scope".  Сама ошибка состоит в том, я так думаю, что какое-то напряжение имеется на входе кнопок. И программа их считывает. Хоть и стоит стягивающий резистор. Не знаю..  

guliyev34
Offline
Зарегистрирован: 17.03.2015

Кнопки подключенны правильно. И прозванивал и проверял на простых программах, все работает. ПРоходит цикл горения светодиодов. А потом пропускает цикл нажатия кнопок. И снова начинают мигать светодиоды.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Последний вариант, дальше без меня, как Вы думаете, сколько времени выполняется Ваш кусок кода из сообщения #3?
Подсказка.

В начале цикла считайте millis() и в конце цикла считайте millis() затем разницу выведите в Serial.

 

guliyev34
Offline
Зарегистрирован: 17.03.2015

Все это работает так. Имеется 3 жизни. И начальный уровень 1. В самом начале включается индикация жизни. И выбирается случайным образом светодиод (пока только один, т.к уровень 1). Заносится номер светодиода в массив. Далее игрок нажимает кнопку, соответствующую светодиоду. При нажатии на кнопку он загорается. Далее идет сравнение того что выдал компьютер (всмысле какой светодиод включил) и то что нажал игрок. После проверки, выбираем, либо уменьшается жизнь, либо идем на следующий уровень. И так до 10 уровня. Смысл игры, кто не поймет из принципа, заключается в повторении комбинации горения светодиодов. Как то так. Еще, вот простой пример кода:


int Knopka1 = 2;
int Led1= 5;

void setup() {
  
  pinMode (Knopka1 , INPUT);
  pinMode (Led1 , OUTPUT);

              }

void loop() {

digitalWrite(Led1, HIGH);
digitalWrite(Led1, LOW); 

          if (digitalRead (Knopka1) == HIGH )
         {
            digitalWrite(Led1, HIGH);
         } 
         else             digitalWrite(Led1, LOW);
         
  } 

 

Получается так, если оставить строки 14-15, то будет светодиод гореть постоянно.. А при нажатии на кнопку, будет просто гореть ярче.. Но никакого выключения не происходит. Если убрать строки 14-15, то все работает нормально. При нажатии на кнопку - светодиод загорается, при отпускании - гаснет. Этого я не пойму. 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

это вы ДУМАЕТЕ что правильно, а нам не видно :)

1 - +5 на резистор, с него на кнопку, с кнопки на землю, с общей точки резистора и кнопки - на пин
( у МК есть подтягивающий внутренний резистор, но вы его в коде не подключили )
при отпущенной кнопке на пине HIGH, при нажатой LOW

2 - +5 на кнопку, с неё на резистор, с него на землю, с общей точки резистора и кнопки - на пин
( у МК нет такого резистора, нужен внешний )

при отпущенной кнопке на пине LOW, при нажатой HIGH

у вас как подсоединены ?

при вставке кода ставьте галочку свернуть и НУМЕРАЦИЯ

guliyev34
Offline
Зарегистрирован: 17.03.2015

Этого я не понял, можно подробнее? Думаю очень быстро. Но все же.. Задача главная, чтобы после того как компьютер запустил серию горящих светодиодов, дал возможность повторить всю комбинацию в ручную. Но он пропускает это.. Например, если взять простой пример из программирования, где мы просто пишем оператор "Readln();" и компьютер ждет нажатия ввода. До этого он никаких действий не предпринимает. Ждет. А тут..

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

две строки от начала лупа - бессмысленны.... зачем они вам ?

guliyev34
Offline
Зарегистрирован: 17.03.2015

По второй схеме. Резистор был 10к

guliyev34
Offline
Зарегистрирован: 17.03.2015

Проверить просто работу светодиодов например. Хочу включить все светодиоды, чтобы убедиться что они работоспособные, и потом выключить. Это как пример. 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

....а тут надо организовать ожидание повтора кода ручками :) , например на секунду, потом сравнивать и если не успел или ошибся = минус жизнь , успел и не ошибся = + жизнь , далее проверка другой комбинацией

guliyev34
Offline
Зарегистрирован: 17.03.2015

Тогда прошу подробнее) Это я не знаю еще..

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

лучше всё сначала сочинять :( , много чего подправить нужно

guliyev34
Offline
Зарегистрирован: 17.03.2015

Так, ну скажите косяки, а я исправлю, и завтра уже выложу что получилось) 

guliyev34
Offline
Зарегистрирован: 17.03.2015

Програма то полностью работает правильно) Жизни считает, индикацию выводит правильно. Сравнение, циклы. Но только не ждет и не записывает нажатие кнопок...  И мне так и не ответили на вопрос во второй части сообщения #10

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

там нет нумерации строк :) , посмотрите как kisoft свой код выложил в #6

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
//int Dead1 = 10; //Если осталась 1 жизнь
//int Dead2 = 9; // Если осталост 2 жизни
//int Dead3 = 8; // Если осталось 3 жизни
//int Knopka1 = 2;
//int Knopka2 = 3;
//int Knopka3 = 4;
//int Led1= 5;
//int Led2= 6;
//int Led3= 7;
#define knopka1 2   // принято с маленьких букв - с больших для других дел :)
#define knopka2 3
#define knopka3 4
#define ledDead1 10
#define ledDead2 9
#define ledDead3 8
#define led1 5
#define led2 6
#define led3 7
boolean lastK1=0;      // для чего эти признаки-флаги ?
boolean lastK2=0;
boolean lastK3=0; 
//=========================================================================
void setup()
{
  Serial.begin (9600);
// строки ниже можно переделать через регистры, но пока так
  pinMode (knopka1,INPUT);    // кнопки переподключите по схеме 1
  digitalWrite(knopka1,HIGH); // включение подтяжки внутренним резистором на 20 kOm , внешние можно убрать
  pinMode (knopka2 ,INPUT);
  digitalWrite(knopka2,HIGH);
  pinMode (knopka3,INPUT);
  digitalWrite(knopka3,HIGH);
  
  pinMode (led1 ,OUTPUT);
  pinMode (led2 ,OUTPUT);
  pinMode (led3 ,OUTPUT);
  
  pinMode (ledDead1 ,OUTPUT);
  pinMode (ledDead2 ,OUTPUT);
  pinMode (ledDead3 ,OUTPUT);
  
  randomSeed (analogRead(0));
}
//     дальше ещё не залез - вопросы не возникают ? :)
//=========================================================================
void loop() {

 

guliyev34
Offline
Зарегистрирован: 17.03.2015

Почему не описываем переменные обычным способом? А описываем через Define? Какие отличия? Кроме самого написания) Да, Вы правы, те булевские переменные лишние) Остальное, как ни странно, понятно)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define knopka1 2   // принято с маленьких букв - с больших для других дел :)
#define knopka2 3
#define knopka3 4
#define ledDead1 10
#define ledDead2 9
#define ledDead3 8
#define led1 5
#define led2 6
#define led3 7

byte liveStart=1;            // байт вмещает 0.....255 , int здесь излишен
byte liveMax=10;             //Максимальное количество уровней
byte deadStart=3;            //Начальное количество жизней

int tempL;                   // эти для чего ?
int tempL1;
int tempK;

boolean massivLed[3];        // это тоже не очень хорошо
boolean massivKnopok[3];     // это тоже не очень хорошо
//=========================================================================
void setup()
{
  Serial.begin (9600);
// строки ниже можно переделать через регистры, но пока так
  pinMode (knopka1,INPUT);    // кнопки переподключите по схеме 1
  digitalWrite(knopka1,HIGH); // включение подтяжки внутренним резистором на 20 kOm , внешние можно убрать
  pinMode (knopka2 ,INPUT);
  digitalWrite(knopka2,HIGH);
  pinMode (knopka3,INPUT);
  digitalWrite(knopka3,HIGH);
  
  pinMode (led1 ,OUTPUT);
  pinMode (led2 ,OUTPUT);
  pinMode (led3 ,OUTPUT);
  
  pinMode (ledDead1 ,OUTPUT);
  pinMode (ledDead2 ,OUTPUT);
  pinMode (ledDead3 ,OUTPUT);
  
  randomSeed (analogRead(0));
}
//=========================================================================
void loop()
{  
  
  
//     дальше ещё не залез - вопросы не возникают ? :)
  
  // Включение индикации жизней
  digitalWrite(Dead3, HIGH);
  digitalWrite(Dead2, HIGH);
  digitalWrite(Dead1, HIGH);
  
   
  while (Dead > 0 && n <= N) //Сама игра до того пока не закончатся жизни
  
// while - плохо , надо по другому

дефайны - сильная штука ( очень сберегает память )

компилятор встретив текст knopka1 заменит его на 2 - это один байт, а int откусит 2 байта

guliyev34
Offline
Зарегистрирован: 17.03.2015

Спасибо, буду знать) А как происходит потом? Сам выбор типа? Целые, вещественные или же логические? Автоматически? define для всех типов данных?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define knopka1 2
#define knopka2 3
#define knopka3 4
#define ledDead1 10
#define ledDead2 9
#define ledDead3 8
#define led1 5
#define led2 6
#define led3 7

byte liveStart=1;
byte liveMax=10;
byte deadStart=3;

int tempL;                   // эти для чего ?
int tempL1;
int tempK;

// boolean massivLed[3];        // это тоже не очень хорошо
// boolean massivKnopok[3];     // это тоже не очень хорошо
// массив не нужен - состояние одого светодиода или кнопки это бит, т.е хватит байта на всё
byte statusLed;       // здесь запоминаем какие светики включали
byte statusKnopok;    // здесь запоминаем какие кнопки нажимались
// сравнение этих байтов покажет правильность нажатий кнопок
//=========================================================================
void setup()
{
  Serial.begin (9600);
  pinMode (knopka1,INPUT);    // кнопки переподключите по схеме 1
  digitalWrite(knopka1,HIGH); // включение подтяжки внутренним резистором на 20 kOm , внешние можно убрать
  pinMode (knopka2 ,INPUT);
  digitalWrite(knopka2,HIGH);
  pinMode (knopka3,INPUT);
  digitalWrite(knopka3,HIGH);
  
  pinMode (led1 ,OUTPUT);
  pinMode (led2 ,OUTPUT);
  pinMode (led3 ,OUTPUT);
  
  pinMode (ledDead1 ,OUTPUT);
  pinMode (ledDead2 ,OUTPUT);
  pinMode (ledDead3 ,OUTPUT);
  
  randomSeed (analogRead(0));
}
//=========================================================================
void loop()
{  
  
  
//     дальше ещё не залез - вопросы не возникают ? :)

компилятор сам знает какие типы использовать

#define vozvestiVkvadrat(X) X*X

далее в коде можно писать N=vozvestiVkvadrat(X) , а не N=X*X

это самое простое что может макроподстановка.....

мне на сутки утром :) , вернусь в четверг

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

про        byte statusLed;       // здесь запоминаем какие светики включали    0 бит отвечает за светик 1 , 1 - за светик 2 , 2 - за 3
три бита это - 0 1 2 3 4 5 6 7 , чтобы сгенерить случайное включение светиков достаточно случайного числа от 1 до 7 , как вывести случайное число на светики - потом

guliyev34
Offline
Зарегистрирован: 17.03.2015

Так, а это будет выполнять то что мне нужно? Ведь у меня уровень до 10 доходит. Т.е будут включаться светодиоды 10 раз. Включение этих 3 светодиодов будет случайным. Разве получится ? Мне же надо чтобы сначала проиграла вся комбинация светодиодов. А потом уже повторить..

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

это уточнение задачи :)

уточните-поправьте алгоритм, на каком уровне- сколько СД из трёх включается ? будет ли на каком-то уровне высвечиваться серия из, например 3 комбинаций одиночных СД или парных ?

пока займусь "диспетчером задач"....

guliyev34
Offline
Зарегистрирован: 17.03.2015

Будет на каждом уровне увеличиваться количество миганий. Т.е используются всего 3 светодиода. Но чем выше уровень, тем больше раз один и тот же светодиод загорится. Сначала проигрывается серия светодиодов. Потом игрок должен повторить всю комбинацию в той же последовательности. Есле ошибся хоть на один светодиод, то отнимается жизнь и начинается уровень сначала этот

guliyev34
Offline
Зарегистрирован: 17.03.2015

Просьба одна, скидывайте пожалуйста промежуточные варианты. Буду разбираться)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

однако неоднозначность возникает :)

как разобрать какие нажатия кнопок относятся к 1-му, 2-му, 3-му кадру из серии ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

guliyev34 пишет:
Просьба одна, скидывайте пожалуйста промежуточные варианты. Буду разбираться)

легко... от занятости правда зависит.... на некоторых вопросах-задачах у миня дети учатся :) берут под "опеку" понравившуюся тему и что-то ваяют, моя не сильно специалист, но поделиться их мыслями и моими скудными познаниями - мы готовы.... 

guliyev34
Offline
Зарегистрирован: 17.03.2015

Как разобрать? Я же писал у себя в коде. Массив кнопок. Если нажимается первая кнопка, в массив заносится значение первого сд. Если второго второе и т.д. А в конце производится сравнение) я тоже только учусь) Раньше занимался аналоговыми устройствами. Сейчас вот решил попробовать цифровую. Мне понравилось ) уже очень много проектов в голове)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define knopka1 2
#define knopka2 3
#define knopka3 4
#define ledDead1 10
#define ledDead2 9
#define ledDead3 8
#define led1 5
#define led2 6
#define led3 7

byte levelStart=1;
byte levelMax=10;
byte deadStart=3;

// переменные и определения для "диспетчера задач"
// описываем перечислительную переменную для задач - пока их три
enum SECTION{sectionOut,sectionIn,sectionResult};     // 0 , 1 , 2 - по умолчанию так сделает компилятор
// sectionOut - вывод на индикацию колва жизней, уровня, задания и др.
// sectionIn - ввод решения задания
// sectionResult - вывод результата решения задачи и др.

// назначаем-порождаем перечислительную переменную для задач типа SECTION
// и присваиваем ей значение sectionOut <=> 0 - т.е. вывод на индикацию колва жизней, уровня, задания и др.
SECTION section=sectionOut;
//=========================================================================
void setup()
{
  Serial.begin (9600);
  pinMode (knopka1,INPUT);    // кнопки переподключите по схеме 1
  digitalWrite(knopka1,HIGH); // включение подтяжки внутренним резистором на 20 kOm , внешние можно убрать
  pinMode (knopka2 ,INPUT);
  digitalWrite(knopka2,HIGH);
  pinMode (knopka3,INPUT);
  digitalWrite(knopka3,HIGH);
  
  pinMode (led1,OUTPUT);
  pinMode (led2,OUTPUT);
  pinMode (led3,OUTPUT);
  
  pinMode (ledDead1,OUTPUT);
  pinMode (ledDead2,OUTPUT);
  pinMode (ledDead3,OUTPUT);
  
  randomSeed (analogRead(0));
}
//=========================================================================
void loop()
{
// начало секции sectionOut
  if(section==sectionOut)
  {
    // .........................
    section=sectionIn;        // переход к выполнению sectionIn
  }
// начало секции sectionIn
  if(section==sectionIn)
  {
    // .........................
    section=sectionResult;    // переход к выполнению sectionIn
  }
// начало секции sectionResult
  if(section==sectionResult)
  {
    // .........................
    section=sectionOut;       // переход к выполнению sectionOut
  }
}
//=========================================================================

пока всё происходит последовательно на каждом проходе лупа.... секция_1, секция_2,секция_3 - так же как и без ифов....
давай вопросы :)

далее организуем "задержку" в секции ввода для нажатия кнопок.....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define knopka1 2
#define knopka2 3
#define knopka3 4
#define ledDead1 10
#define ledDead2 9
#define ledDead3 8
#define led1 5
#define led2 6
#define led3 7

byte levelStart=1;
byte levelMax=10;
byte deadStart=3;

// переменные и определения для "диспетчера задач"
// описываем перечислительную переменную для задач - пока их три
enum SECTION{sectionOut,sectionIn,sectionResult};     // 0 , 1 , 2 - по умолчанию так сделает компилятор
// sectionOut - вывод на индикацию колва жизней, уровня, задания и др.
// sectionIn - ввод решения задания
// sectionResult - вывод результата решения задачи и др.

// назначаем-порождаем перечислительную переменную для задач типа SECTION
// и присваиваем ей значение sectionOut <=> 0 - т.е. вывод на индикацию колва жизней, уровня, задания и др.
SECTION section=sectionOut;
// переменная для засечки времени в системе МК
unsigned long oldMillis;
//=========================================================================
void setup()
{
  Serial.begin (9600);
  pinMode (knopka1,INPUT);    // кнопки переподключите по схеме 1
  digitalWrite(knopka1,HIGH); // включение подтяжки внутренним резистором на 20 kOm , внешние можно убрать
  pinMode (knopka2 ,INPUT);
  digitalWrite(knopka2,HIGH);
  pinMode (knopka3,INPUT);
  digitalWrite(knopka3,HIGH);
  
  pinMode (led1,OUTPUT);
  pinMode (led2,OUTPUT);
  pinMode (led3,OUTPUT);
  
  pinMode (ledDead1,OUTPUT);
  pinMode (ledDead2,OUTPUT);
  pinMode (ledDead3,OUTPUT);
  
  randomSeed (analogRead(0));
  
  oldMillis=millis();   // засечка времени в системе МК - "вкл. секундомера"
}
//=========================================================================
void loop()
{
// начало секции sectionOut
  if(section==sectionOut)
  {
    // .........................
    section=sectionIn;        // переход к выполнению sectionIn
  }
  
  
  
// начало секции sectionIn
  if(section==sectionIn)
  {
    if((millis()-oldMillis)<1000)    // делаем что-то пока разница
                                     // текущего времени МК и секундомера не станет больше 1 секунды
                                     // т.е. - это время на принятие решения и нажатия кнопок
    {
      // нажатие кнопок, формирование результата ответа
      // .......................................................
    }
    else
    {
      section=sectionResult;    // переход к выполнению sectionIn
    }
  }
  
  
  
// начало секции sectionResult
  if(section==sectionResult)
  {
    // .........................
    section=sectionOut;       // переход к выполнению sectionOut
  }
}
//=========================================================================

"диспетчер задач" готов

guliyev34
Offline
Зарегистрирован: 17.03.2015

"sectionIn" Это переменная, которая будет хранить в себе результат ввода кнопок, а "sectionResult" вывод результата, т.е правильно игрок ввел или нет, я правильно понял? Ого, я так понимаю, что мы разбили всю игру на несколько секций. Сначала выводим все (задание, уровень), после этого переходим на секцию 2, где уже играет игрок, и после этого мы переходим на секцию 3, где как раз и проверяется и выводится результат. И пока не сделается 1 или 2 секция, мы никак не перейдем на 3 этап. Класс. Впечатляет)

guliyev34
Offline
Зарегистрирован: 17.03.2015

millis() мы будем использовать только в секции 2? И пока не выволнится условие в 65 строке, мы не перейдем дальше? В скобках значение в мс? 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

запуск :
- выполняется секция вывод задания, строка #57 - переход на выполнение строк #68...71

- они выполнятся много раз ( пока не пройдёт секунда эти строки выполнятся раз 100.....50000 ( неохота считать ), через секунду выполнится переход ( строка #74 ) к строкам #82....85

- выведутся результаты ответа

- и снова новый вывод задания

guliyev34
Offline
Зарегистрирован: 17.03.2015

Ну я так и думал.  В принципе что будет в секциях 1 и 3, я представляю. А вот в секции 2.. 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

guliyev34 пишет:

millis() мы будем использовать только в секции 2? И пока не выволнится условие в 65 строке, мы не перейдем дальше? В скобках значение в мс? 

такая задержка нужна только в секции_2
в секциях 1 и 3 - можно обойтись простыми делеями(Х)

пока ВЫПОЛНЯЕТСЯ условие в 65 - будем ждать ввода кнопок, не выполняется - дальше идём
да, millis() оперирует миллисекундами....

важно ! МК не стоит на месте ! он всё время исполняет код от начала лупа до конца.... в цикле, он не может остановиться :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

guliyev34 пишет:

Ну я так и думал.  В принципе что будет в секциях 1 и 3, я представляю. А вот в секции 2.. 

да, тут надо думать :)
и организовать считывание кнопок и формирование результата с учётом что этот кусок кода выполнится за секунду 100500 раз....

guliyev34
Offline
Зарегистрирован: 17.03.2015

SU-27-16 пишет:

важно ! МК не стоит на месте ! он всё время исполняет код от начала лупа до конца.... в цикле, он не может остановиться :)

А функция millis()  дает такую возможность? Она же, как я понимаю, дает зажержку? 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

строка #26 - это для одного секундомера... их можно определить, например 10 !
но придётся описать 10 фрагментов кода как в #65.....75
( и у каждого из 10-ти указать период на выбор 1 миллисек..........50 дней ) см. millis()

забыл..... ой-ой-ой..... надо перезапустить секундомер в строке #57A

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define knopka1 2
#define knopka2 3
#define knopka3 4
#define ledDead1 10
#define ledDead2 9
#define ledDead3 8
#define led1 5
#define led2 6
#define led3 7

byte levelStart=1;
byte levelMax=10;
byte deadStart=3;

// переменные и определения для "диспетчера задач"
// описываем перечислительную переменную для задач - пока их три
enum SECTION{sectionOut,sectionIn,sectionResult};     // 0 , 1 , 2 - по умолчанию так сделает компилятор
// sectionOut - вывод на индикацию колва жизней, уровня, задания и др.
// sectionIn - ввод решения задания
// sectionResult - вывод результата решения задачи и др.

// назначаем-порождаем перечислительную переменную для задач типа SECTION
// и присваиваем ей значение sectionOut <=> 0 - т.е. вывод на индикацию колва жизней, уровня, задания и др.
SECTION section=sectionOut;
// переменная для засечки времени в системе МК
unsigned long oldMillis;
//=========================================================================
void setup()
{
  Serial.begin (9600);
  pinMode (knopka1,INPUT);    // кнопки переподключите по схеме 1
  digitalWrite(knopka1,HIGH); // включение подтяжки внутренним резистором на 20 kOm , внешние можно убрать
  pinMode (knopka2 ,INPUT);
  digitalWrite(knopka2,HIGH);
  pinMode (knopka3,INPUT);
  digitalWrite(knopka3,HIGH);
  
  pinMode (led1,OUTPUT);
  pinMode (led2,OUTPUT);
  pinMode (led3,OUTPUT);
  
  pinMode (ledDead1,OUTPUT);
  pinMode (ledDead2,OUTPUT);
  pinMode (ledDead3,OUTPUT);
  
  randomSeed (analogRead(0));
  
  oldMillis=millis();   // засечка времени в системе МК - "вкл. секундомера"
}
//=========================================================================
void loop()
{
// начало секции sectionOut
  if(section==sectionOut)
  {
    // .........................
    section=sectionIn;        // переход к выполнению sectionIn
    oldMillis=millis();       // засечка времени в системе МК - "вкл. секундомера"
  }
  
  
  
// начало секции sectionIn
  if(section==sectionIn)
  {
    if((millis()-oldMillis)<1000)    // делаем что-то пока разница
                                     // текущего времени МК и секундомера не станет больше 1 секунды
                                     // т.е. - это время на принятие решения и нажатия кнопок
    {
      // нажатие кнопок, формирование результата ответа
      // .......................................................
    }
    else
    {
      section=sectionResult;    // переход к выполнению sectionIn
    }
  }
  
  
  
// начало секции sectionResult
  if(section==sectionResult)
  {
    // .........................
    section=sectionOut;       // переход к выполнению sectionOut
  }
}
//=========================================================================

 

guliyev34
Offline
Зарегистрирован: 17.03.2015

SU-27-16 пишет:

и организовать считывание кнопок и формирование результата с учётом что этот кусок кода выполнится за секунду 100500 раз....

Можно же сделать так. Например проморгали СД 1, 3, 2. Потом нажимаем кнопки: 1, 2 .. И тут же происходит прерывание цикла. Т.к уже ввели неправильно. 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

guliyev34 пишет:

SU-27-16 пишет:

и организовать считывание кнопок и формирование результата с учётом что этот кусок кода выполнится за секунду 100500 раз....

Можно же сделать так. Например проморгали СД 1, 3, 2. Потом нажимаем кнопки: 1, 2 .. И тут же происходит прерывание цикла. Т.к уже ввели неправильно. 

про уточнение задачи моя уже говорил....

от постановки задачи зависит её решение !
Например проморгали СД 1, 3, 2. Потом нажимаем кнопки: 1, 2 .. И тут же происходит прерывание цикла.

прерывание цикла - не происходит, заканчивается время его исполнения ( прерывания - это другое )
что значит поморгали ?

вкл СД1 на 0,5 сек, пауза 0,5 сек, вкл СД3 на 0,5 сек, пауза 0,5 сек, вкл СД2 на 0,5 сек, пауза 0,5 сек
....затем для правильного ответа жмём кнопки в последовательности 132 с максимальной скоростью возможной для пальца ? 

guliyev34
Offline
Зарегистрирован: 17.03.2015

Давайте начнем по порядку? Начнем с первой секции. Светодиоды будут моргать в случайном порядке. Это будет выбираться с помощью функции random(). Не хочу чтобы какой-то СД горел 2 раза подряд. Я в своем первоначальном коде это прописывал с помощью цикла while. Теперь вопрос, куда будут записываться значения светодиодов? Их может быть 10. Они же где-то должны храниться? Я делал массив. Как вы думаете это сделать ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

успел за секунду нажать 132 - +жизнь, +уровень
не успел за секунду или ошибся - -жизнь, -уровень

это надо прописать в секции_3

guliyev34
Offline
Зарегистрирован: 17.03.2015

SU-27-16 пишет:

прерывание цикла - не происходит, заканчивается время его исполнения ( прерывания - это другое )
что значит поморгали ?

Прерывание в том плане, что если мы уже нажали не ту кнопку, то смысла продолжать дальше цикл бесполезно. break самое то. Я так думаю. Поморгали. Значит что загорелся СД 1, потом погас, потом загорелся СД 3, погас, и СД 3 загорел и погас.