Отслеживание ивентов на кнопке

Тема в разделе "Arduino & Shields", создана пользователем Roman R, 6 фев 2019.

  1. Roman R

    Roman R Нуб

    Всем привет, мигаю лампочками, и столкнулся с проблемой. Задача что бы лампочки работали в режиме "гирлянды".Начинали мигать по кнопке, и после еще одного нажатия кнопки прекращали это делать, когда закончится цикл. У меня естественно не получается ничего, потому что всё в одном потоке и нажатие кнопки оно просто не регистрирует когда уже зашло в цикл. Как решать подобные задачи, какие то либы может есть?В какую сторону думать?Что почитать?
    Код пока такой:
    Код (C++):

    int button = 2;
    int state = false;
    void setup()
    {
      Serial.begin(9600);
      Serial.println("Test button ...");
      pinMode(button, INPUT);
      pinMode(11, OUTPUT);
      pinMode(10, OUTPUT);
      pinMode(9, OUTPUT);
      pinMode(12, OUTPUT);
      pinMode(13, OUTPUT);
    }

    void run() {
      digitalWrite(11, HIGH);
      delay(500);
      digitalWrite(11, LOW);
      digitalWrite(10, HIGH);
      delay(500);
      digitalWrite(10, LOW);
      digitalWrite(9, HIGH);
      delay(500);
      digitalWrite(9, LOW);
      digitalWrite(13, HIGH);
      delay(500);
      digitalWrite(13, LOW);
      digitalWrite(12, HIGH);
      delay(500);
      digitalWrite(12, LOW);
    }

    void loop()
    {
      if (digitalRead(button) == HIGH) {
      state = !state;
      }

      Serial.println(state);
      if (state) {
      run();
      }
    }
     
     
    Последнее редактирование модератором: 6 фев 2019
  2. b707

    b707 Гуру


    полностью переделывать логику программы, избавляться от dekay
    Ищите пример blink without delay - там наглядно показан принцип
     
    arkadyf нравится это.
  3. parovoZZ

    parovoZZ Гуру

    Всё очень просто. На таймере выставляешь необходимую паузу. Проц загоняешь в остановку. По прошествии паузы таймер будит проц, делаешь что-то, затем опять выставляешь необходимую паузу и снова в остановку. Кнопку на прерывание, либо же её цикличный опрос.
     
  4. Roman R

    Roman R Нуб

    Не знаю парни, может вопрос как то не понятно поставил. Но оказывается ардуино поддерживает то что мне надо было на уровне железа, прерываниями.Вот оптимальное решение, которое работает так как я хотел:
    int button = 2;
    int state = false;
    void setup()
    {
    Serial.begin(9600);
    Serial.println("Test button ...");
    pinMode(button, INPUT);
    pinMode(11, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(13, OUTPUT);
    attachInterrupt(0,run,RISING);

    }

    void run() {
    state=!state;

    }


    void loop()
    {
    if(digitalRead(button)==LOW && !state){
    digitalWrite(11, HIGH);
    delay(500);
    digitalWrite(11, LOW);
    digitalWrite(10, HIGH);
    delay(500);
    digitalWrite(10, LOW);
    digitalWrite(9, HIGH);
    delay(500);
    digitalWrite(9, LOW);
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
    delay(500);
    digitalWrite(12, LOW);


    }
    Serial.println (state);
    }
     
  5. b707

    b707 Гуру

    соскочил? :) ну и зря
    Прерываний на Атмеге всего ничего, да и далеко не все можно можно сделать прерываниями.
    Осваивать код без delay() тебе все равно придется.
     
  6. 26, вообще-то
     
  7. b707

    b707 Гуру

    во-первых уже поправился - знал ведь. что обязательно найдется грамотный и влезет :)
    Во-вторых, суть не в этом - проблема ТС не в том, что ему нужно прерывание, а в том что он не умеет грамотно писать программы. Использование прерывания в его случае - это читерство :)
     
  8. parovoZZ

    parovoZZ Гуру

    так ведь в дашиках все описано.
     
  9. parovoZZ

    parovoZZ Гуру

    43, вообще-то
     
  10. Roman R

    Roman R Нуб

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

    parovoZZ Гуру

    Плохая практика - это писать такие простыни без особой на то нужды:
    А вот такое
    вообще не практикуется в однопоточных алгоритмах.
     
  12. Roman R

    Roman R Нуб

    тут вопрос в прерывании, какая разница что я в лупе делаю, хоть простыня, хоть эти костыли с таймерами, всё равно я бы колбек функцию использовал.Это надежнее, наглядние, и легче поддерживать потом
     
  13. Roman R

    Roman R Нуб

    Заменю щас делей на что то другое, тяжелое, и кнопка не будет работать корректно уже. И опять таки я буду юзать прерывание.Мой вопрос почему прерывание плохая практика. А не в делеях.Изначально было дело не в них
     
  14. parovoZZ

    parovoZZ Гуру

    Кто сказал?
    Каждой задаче свое решение.
     
  15. Roman R

    Roman R Нуб

     
  16. parovoZZ

    parovoZZ Гуру

    ? Не то, что слов, даже букв похожих нет.
     
  17. Roman R

    Roman R Нуб

    Вопрос.
     
  18. b707

    b707 Гуру

    никто не говорил. что прерывание - плохая практика. Плохая практика - писать подобный говнокод (а это именно гавнокод) - а потом решать возникшие проблемы прерыванием.
    Ошибаетесь, изначальная ваша проблема именно в делеях. Написали бы нормальную программу - и прерывания не понадобились.
     
  19. Roman R

    Roman R Нуб

    я просто не вам писал видимо.И вы не видели.Покажите пожалуйста не говнокод, для моей задачи.Наглядно будет сразу понятно всё.Делей если вам не нравится можете заменить чем угодно тяжелым что вам нравится что займет поток полностью
     
  20. qwone

    qwone Гик

    Это как рукопашный бой в бою. Да использовать можно, но только в том случае когда прое**л все остальное. А так вариантов куча. Я например использую автоматы.
     
    Daniil нравится это.