Бесконечный цикл.

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

  1. Lagvin

    Lagvin Нерд

    Уважаемые форумчане. Начал работать со скетчами на ардуино.Нужен совет.
    Как уйти в бесконечный цикл. Т.е. Прикратковременном нажатии на кнопку первый светодиод загорается и при отпускании тухнет. Второй уходит в бесконечный цикл мигания до того времени пока не нажмем reset.

    Я создал такую программу, но она мне кажется не правильной, хотя все работает.

    Может у кого есть идеи.

    Код (Text):

    #define BUTTON_PIN 2
    #define LED_PIN 10
    #define LEDD_PIN 13
    #define BLINK_DELAY 500

    bool LedState = false;
    bool Button = true;
    bool mer = false;

    void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
    pinMode(LEDD_PIN, OUTPUT);

    }

    void loop() {
    bool isButton = digitalRead(BUTTON_PIN);
    if (!isButton && Button) {
    digitalWrite(LEDD_PIN, HIGH);
    mer = true;
    if (mer) {
    digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
    }
    }
    else {digitalWrite(LEDD_PIN, LOW);
    if (mer) {
    digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);}
    }
    }

     
     
  2. vvr

    vvr Инженерище

    надо добавить борьбу с дребезгом контактов кнопки и вперёд!
     
  3. Lagvin

    Lagvin Нерд

    Добавил. Но это не главное сейчас. Мне нужно узнать правильно ли составлена программа и есть ли альтернативы ей. Может условие за else не совсем и нужно. Либо как-то по другому...
    Код (Text):

    #define BUTTON_PIN 2
    #define LED_PIN 10
    #define LEDD_PIN 13
    #define BLINK_DELAY 500

    bool LedState = false;
    bool Button = true;
    bool mer = false;

    void setup() {
     pinMode(BUTTON_PIN, INPUT_PULLUP);
     pinMode(LED_PIN, OUTPUT);
     pinMode(LEDD_PIN, OUTPUT);

    }

    void loop() {
     bool isButton = digitalRead(BUTTON_PIN);
     delay (20);// добавил борьбу с дребезгом.
     if (!isButton && Button) {
     digitalWrite(LEDD_PIN, HIGH);
     mer = true;
     if (mer) {
     digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
     }
     }
     else {digitalWrite(LEDD_PIN, LOW);
     if (mer) {
     digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);}
     }
    }

     
     
  4. vvr

    vvr Инженерище

    а зачем повторяете два раза

    if (mer) {
    digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);}
     
  5. Lagvin

    Lagvin Нерд

    А без второго раза не работает.
     
  6. vvr

    vvr Инженерище

    сделал код более читаемым (пользуйтесь Сtrl + T - будет легче)
    разобрался, всё нормуль.


    Код (Text):

    void loop()
    {
      bool isButton = digitalRead(BUTTON_PIN);
      delay (20);
      if (!isButton && Button)
      {
        digitalWrite(LEDD_PIN, HIGH);
        mer = true;
        if (mer)
        {
          digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
        }
      }
      else
      {
        digitalWrite(LEDD_PIN, LOW);
        if (mer)
        {
          digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
        }
      }
    }
     
     
  7. Lagvin

    Lagvin Нерд

    Я как бы преследую другую цель, хочу научиться уходть в бесконечный цикл не зависящий от продолжения программы и прерываний.
    Объясню по другому:
    Нажимаю на кнопку она запускает цикл (допустим моргание светодиода), и этот цикл выполняется всегда, даже если в программе стоит передача данных по радиочастоте или др. только при нажатии reset цикл обнуляется. А кнопка которая запускала будет использоваться для другого действия в программе, но это по сути не важно.
     
  8. X-Dron

    X-Dron Гик

    Многозадачность на контроллерах, даже промышленных не поддерживается. Всегда в определенный момент выполняется только одна задача. Есть планировщики задач, которые прерывают одну и ставят на выполнение другую, но работает в текущий момент только одна. Для того, чтобы разгрузить основной процессор ставятся "сопроцессоры", например, коммуникационные модули.
    процесс Loop это и есть бесконечный цикл, который всегда исполняется. Вы только прменьше delay-ев используйте. :)
    А это как так?
    При нажатии на reset Loop() точно перезапустится, но только после Setup() :).
    Вы давно с контроллерами знакомы?
     
  9. Lagvin

    Lagvin Нерд

    По сути эта программа - продолжение обзора "Умная жерлица" ;
    С контроллером про мини, который у меня сейчас в единственном экземпляре знаком пару дней.
    Задумка программы такова, что при нажатии на кнопку (после -это будет геркон) светодиод на жерлице должен мигать постоянно (чтобы ночью было видно куда бежать), но при этом сигнал о срабатывании должен передаться по радиочастоте не прерывая мигания.
     
  10. X-Dron

    X-Dron Гик

    Жерлица, это, по-моему, круто. Тогда я не понимаю, откуда у Вас берутся такие вопросы по программированию.

    по коду
    Код (Text):
    #define BUTTON_PIN 2
    #define LED_PIN 10
    #define LEDD_PIN 13
    #define BLINK_DELAY 500

    bool LedState = false;
    bool Button = true;
    bool mer = false;

    void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
    pinMode(LEDD_PIN, OUTPUT);
    }

    void loop()
    {
      bool isButton = digitalRead(BUTTON_PIN);
      delay (20);
      if (!isButton && Button)
      {
        digitalWrite(LEDD_PIN, HIGH);
        mer = true;
        if (mer)
        {
          digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
        }
      }
      else
      {
        digitalWrite(LEDD_PIN, LOW);
        if (mer)
        {
          digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
        }
      }
    }
    У меня 2 замечания
    переменная Button только объявляется и инициализируется в true, но нигде не используется.
    поэтому if (!isButton && Button) равносильно if (!isButton).
    Код (Text):
        if (mer)
        {
          digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);
        }
    выполняется 2 раза и на if и на else. это выражение выносится за пределы if (!isButton && Button)

    сейчас соберусь с мыслями и попробую написать покороче, строчек в 5 в void loop() и без использования библиотек.
     
  11. X-Dron

    X-Dron Гик

    Ошибся, кода в void loop() всего 4 строчки, комментарии не считаем. :)
    Должно работать. Кнопка в нажатом состоянии выдает на контроллер логический ноль(false), в отпущенном - true. Мигание сбрасывается нажатием на reset, программа просто перезапускается.
    Если дальше нигде не будешь использовать delay(), то с миганием будет все нормально, даже если будут использоваться передача данных по радио. Для того, чтобы появились проблемы с миганием, длительность цикла void loop() должна приближаться к BLINK_DELAY. Сделать это без использования delay() на ардуино тяжело. :)
    Код (Text):
    #define BUTTON_PIN 2
    #define LED_PIN 10
    #define LEDD_PIN 13
    #define BLINK_DELAY 500

    bool Button;
    bool mer = false;

    void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
    pinMode(LEDD_PIN, OUTPUT);
    }

    void loop()
    {
      Button = !digitalRead(BUTTON_PIN); //считываем и нормализуем кнопку
      digitalWrite(LEDD_PIN, Button); //Если нажата кнопка, то светится светодиод LEDD
      if (Button) mer = true;
      //если была нажата клавиша, а затем ее отпустили, то на светодиод LED выводится симметричный меандр
      //с длительностью импульса BLINK_DELAY миллисекунд
      digitalWrite(LED_PIN, ((millis()/BLINK_DELAY)%2) && mer && !Button);
    }
     
  12. Lagvin

    Lagvin Нерд

    Спасибо! Все хорошо, но не очень. Маленькая загвоздка: При нажатии на кнопку(геркон, он будет установлен на теле жерлицы, а магнит на катушке) и удержании ее ( по сути магнит на катушке может остановиться напротив геркона, а тот в свою очередь сомкнет контакты) цикл LED останавливается.
    Сейчас еще сам покумекаю над этой блестящей на мой нубский взгляд программой.

    P/S/ совсем не понял про симметричный меандр. Буду разбираться.
     
    Последнее редактирование: 25 фев 2015
  13. Lagvin

    Lagvin Нерд

    Да, забыл про Button в скетче. Я выдрал из двух(чужих) программ вроде как главное. Слепил. Через 6 часов добавил. И как-бы получилось. Но написание Вашей программы - это то что я хотел. Но нужно доработать.
     
  14. X-Dron

    X-Dron Гик

    Никакие циклы не останавливаются. Loop работает все время без остановки
    В программе реализован такой алгоритм.
    LEDD горит, если нажата клавиша и пока она нажата. Если ее отпустить, то LEDD погаснет, если нажать снова, то загорится опять.
    LED мигает, если клавишу нажали, а потом отпустили. Если снова нажали клавишу, то мигать перестает. Если отпустить снова, то опять мигает.
    Меандр это и есть мигание. Симметричный - время горения равно времени погашенного состояния
     
  15. X-Dron

    X-Dron Гик

    Попробуй еще такой код на LED
    digitalWrite(LED_PIN, (((millis()/BLINK_DELAY)%2) && mer && !Button) || (((millis()/200)%2) && Button));
    :)
    Если клавиша нажата, то диод мигает часто, если была нажата, но уже отпущена - реже
     
    Lagvin нравится это.
  16. Lagvin

    Lagvin Нерд

    ПОЛУЧИЛОСЬ!!!

    digitalWrite(LED_PIN, ((millis()/BLINK_DELAY)%2) && mer ) ; \\ убрал !Button
    Хотя Ваше предложение еще лучше, так можно отслеживать вращение катушки
     
  17. Lagvin

    Lagvin Нерд

    Вот еще бы подсказали как сделать так, чтобы если в самом начале (при установке жерлицы) кнопка нажата(магнит на катушке случайно совпал с герконом), то программа не запускается и горит, допустим, третий светодиот (красный). Это было бы для начала сказка.
     
  18. X-Dron

    X-Dron Гик

    А смысл? У Вас же уже есть целых 2 индикатора, что кнопка нажата?
    Установили жерлицу, видите, что LED мигает быстро, приспустили немного леску, чтобы магнит отошел от геркона и нажали reset. Тем самым поставив жерлицу в режим ожидания.
    Можно еще сделать не по срабатыванию геркона, а по изменению его состояния. Тогда программа будет такая
    Код (Text):
    #define BUTTON_PIN 2
    #define LED_PIN 10
    #define LEDD_PIN 13
    #define BLINK_DELAY1 500
    #define BLINK_DELAY2 200

    bool Button, Button_old;
    bool mer = false;

    void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
    pinMode(LEDD_PIN, OUTPUT);
    }

    void loop()
    {
      Button = !digitalRead(BUTTON_PIN); //считываем и нормализуем кнопку
      digitalWrite(LEDD_PIN, Button); //Если нажата кнопка, то светится светодиод LEDD
      // устанавливаем mer по изменению состояния клавиши
      if ((Button && !Button_old) || (!Button && Button_old)) mer = true;
      Button_old = Button;
      digitalWrite(LED_PIN, (((millis()/BLINK_DELAY1)%2) && mer && !Button) ||
                            (((millis()/BLINK_DELAY2)%2) && mer &&  Button));
    }
     
  19. Lagvin

    Lagvin Нерд

    Все прекрасно работает, но задумка не в этом.
    Можно ли в СЕТАПЕ создать условие, при котором не выполнение его ЛУП не запустится.
     
  20. geher

    geher Гуру

    Код (Text):
    if () {
      ... // что-то делаем
      while(1){}; // "зависаем"
    }
    Вместо 1 в условии while можно поставить какое-нибудь условие "возврата к жизни" с отрицанием.
     
    Lagvin нравится это.