Внешние прерывания нопкой

Тема в разделе "Arduino & Shields", создана пользователем Hottab, 16 мар 2015.

  1. Hottab

    Hottab Нерд

    Всем привет, столкнулся с проблемой прерываний. Возможно ли осуществлять переход между бесконечными циклами с помощью них? Допустим у меня имеется 3 режима работы устройства и при нажатии кнопки один режим, должен заменять другой, но что то вобще не получается прервать бесконечный цикл, в чём тогда смысл прерываний? вот что мы имеем наши режимы в switch цикле:
    Код (Text):
    switch (ledLevel){//выбор режима
     
        case 1://1-й режим
        digitalWrite(led,HIGH);//1 моргание сигнализатор
        delay(400);//задержка
        digitalWrite(led,LOW);
        for(;;)//пустой бесконечный цикл
        {
          int  val = analogRead(A1);//чек сенсора
          digitalWrite(ledRed,LOW);//красный светодиод выкл
          digitalWrite(ledGreen,HIGH);//зелёный светодиод вкл
         
          if(val >= 330)//не горит ли подсветка
          {
          digitalWrite(ledGreen,LOW);//выключаем хзелный сд
          digitalWrite(ledRed,HIGH);//включаем красный, показывая что в цикле включения реле
          digitalWrite(rely,HIGH);//вкл реле
          delay(300);//3 сек задержка
          digitalWrite(rely,LOW);//выкл реле
          delay(10000); //100 сек
          }
         
        } //конец бесконечного пустого цикла
         
      break;//конец 1-го режима, переход к выбору case
     
     
     
      case 2://2-й режим
        digitalWrite(led,HIGH);
        delay(400);
        digitalWrite(led,LOW);
        delay(400);
        digitalWrite(led,HIGH);
        delay(400);
        digitalWrite(led,LOW);
     
     
      for(;;)//бесконечный цикл
      {
       
      int  val = analogRead(A1);//чек сенсора
      digitalWrite(ledRed,LOW);//красный светодиод выкл
      digitalWrite(ledGreen,HIGH);//зелёный светодиод вкл
          if(val >= 330)// не горит ли подсветка
          {
           
            digitalWrite(ledGreen,LOW);//зелёный светодио выкл
            digitalWrite(ledRed,HIGH);//красный светодиод вкл
            delay(10000);  
            for(int i=0; i <=25; i++)//  счётчик
          {
            //int  val01 = analogRead(A1);
          digitalWrite(ledRed,LOW);//выкл сд
          delay(300);//3сек задержка
          digitalWrite(ledRed,HIGH);//вкл сд
          delay(300);//3 сек задержкжа
          if(val >= 330)//проверил АЦП, если больше 330, то выполнять условия, если нет, перейти к началу цикла фор
          {
            digitalWrite(rely,HIGH);//вкл реле
            delay(300);
            digitalWrite(rely,LOW);//выкл реле
            delay(10000);
            break;//выход из цикла
          }
          else if(i = 25) break;
          }
        }
      }
        break;
       
        case 3://3-й режим
     
        digitalWrite(led,HIGH);//1
        delay(400);
        digitalWrite(led,LOW);
        delay(400);
        digitalWrite(led,HIGH);//2
        delay(400);
        digitalWrite(led,LOW);
        delay(400);
        digitalWrite(led,HIGH);//3
        delay(400);
        digitalWrite(led,LOW);
        for(;;){
        digitalWrite(ledRed,LOW);//красный светодиод выкл
        digitalWrite(ledGreen,HIGH);//зелёный светодиод вкл
        int  val = analogRead(A1);//переменая фоторезистора
        if(val >= 330)//если АЦП выше 330 выполять условия цикла(вкл подсветка телефона, 1-й этап)
        {
        digitalWrite(ledGreen,LOW);//зелёный светодио выкл
        digitalWrite(ledRed,HIGH);//красный светодиод вкл
        for(int i=0; i <=5; i++)//  счётчик
          {
           
            int  val = analogRead(A1);
            digitalWrite(ledRed,LOW);//выкл сд
            delay(100);//3сек задержка
          digitalWrite(ledRed,HIGH);//вкл сд
          delay(100);//3 сек задержкжа
          if(i = 5)//проверил АЦП, если больше 330, то выполнять условия, если нет, перейти к началу цикла фор
          {
            digitalWrite(rely,HIGH);//вкл реле
            delay(300);
            digitalWrite(rely,LOW);//выкл реле
            delay(10000);
            break;//выход из цикла
          }
          else if(val <= 330)
          {
            break;
          }
           
          }
        }
        break;
        default:
        digitalWrite(ledGreen,LOW);//зелёный светодио выкл// код для выполнения
        break;
      }
    }
    Подскажите каким образом можно решить проблему, спасибо!
     
  2. geher

    geher Гуру

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

    Hottab Нерд

    Ставил я подобным образом, дело в том что в кейсе есть внутренние бесконечные циклы и они не дают переключатся, если сделать внутри каждого проверку не равна ли переменная кнопки такому то значению, если да, то break, а каждое нажатие кнопки увеличивало бы переменную на ++, но программа будет работать не мгновенно, например если она висит в таймере delay, она же не переключится по нажатию?
     
  4. geher

    geher Гуру

    delay придется менять на millis. чтобы в момент ожидания можно было проверить условие выхода.
    И проверять в каждом вложенном цикле. чтобы и их прерывать.
    Просто перескочить из цикла в цикл за счет прерывания не получится.
    Конечно: можно в фуккции прерывания подделать в стеке адрес возврата, но тут придется помимо прочего следить за корректным состоянием стека, чтобы не получилось его роста за счет того, что возврат может осуществляться минуя вложенные вызовы функций.
     
    Hottab нравится это.
  5. Alex19

    Alex19 Гуру

    Ваш подход не совсем верный, намучаетесь Вы с ним.

    Зачем бесконечные циклы, когда loop бесконечен?
    Можно просто сделать на конечном автомате + switch режимов и шагов. Почитайте, это позволит уйти от бесконечных циклов и сделает программу более прозрачной и понятной.

    О delay уже написал geher.

    По постоянной проверке почитайте тут. Сам вначале остановился, на последнем варианте, потом вернулся к простым проверкам.
     
    Hottab нравится это.
  6. Hottab

    Hottab Нерд

    Спасибо за информацию, почитаю рекомендации, надеюсь поможет! АТо уже весь мозг себе изнасиловал как всё это реализовать, ещё и памяти на тиньки 13-й не хватает на всё(