Светодиоды и кнопка

Тема в разделе "Arduino & Shields", создана пользователем ejik_off, 12 май 2018.

  1. ejik_off

    ejik_off Нуб

    Приветствую всех любителей поломать голову и не только :)
    Только начинаю разбираться с ардуинкой и собственно вот сижу ломаю голову над задачкой.
    Собрал небольшую схемку, а вот с программой не могу разобраться. Есть RGB-светодиод, хотел cделать вроде проблескового моячка. По нажатию на кнопку (нажал-отпустил) должен включатся поочередно красный\синий светодиод, еще раз нажал-отпустил потухли.
    Почему то на ум приходит только сделать через цикл, но тогда не получается выйти из цикла. подскажите что не так в скече и вообще правильный ли подход?
    Код (C++):
    int r = 4;
    int g = 3;
    int b = 2;
    boolean butt;
    boolean butt_flag;

    void setup() {
      // put your setup code here, to run once:
    pinMode(r, OUTPUT);
    pinMode(g, OUTPUT);
    pinMode(b, OUTPUT);
    pinMode(5, INPUT);
    Serial.begin(9600);
    }

    void loop() {
     
      // put your main code here, to run repeatedly:
    butt = digitalRead(5);
    if (butt == 1 && butt_flag == 0 ) {
      Serial.println(butt);
      Serial.println(butt_flag);
      butt_flag = 1;
      while (butt_flag == 1){
      digitalWrite(r, HIGH); //включаем красный
      delay(500); //ждем 500 Мс
      digitalWrite(r, LOW); //выключаем красный
      digitalWrite(b, HIGH); //включаем синий
      delay(500); //ждем 500 Мс
      digitalWrite(b, LOW); //выключаем синий
      }
      }
      if ( butt == 0 && butt_flag == 1 ){
        Serial.println(butt);
        Serial.println(butt_flag);
        butt_flag = 0;
       
        digitalWrite(r, LOW);
        digitalWrite(b, LOW);
      }
     
    }
     
  2. ostrov

    ostrov Гуру

    Зачем выйти из цикла? Куда?
     
  3. ejik_off

    ejik_off Нуб

    при первом нажатии на кнопку отрабатывает этот код
    Код (C++):
    digitalWrite(r, HIGH); //включаем красный
      delay(500); //ждем 500 Мс
      digitalWrite(r, LOW); //выключаем красный
      digitalWrite(b, HIGH); //включаем синий
      delay(500); //ждем 500 Мс
      digitalWrite(b, LOW); //выключаем синий
    при втором нажатии светодиод прекращает моргать, т.е тухнет
    сейчас при первом нажатии светодиод начинает моргать и сколько бы я не нажимал на кнопку светодиод продолжает моргать. как я понимаю программа не выходит из цикла
     
  4. ostrov

    ostrov Гуру

    Кнопка притянута к нулю резистором?
     
  5. ejik_off

    ejik_off Нуб

    К минусу
     
    Последнее редактирование: 13 май 2018
  6. Daniil

    Daniil Гуру

    чему равна переменная butt_flag?
     
  7. ostrov

    ostrov Гуру

    Все верно, внутри цикла моргания флаг, по которому выход, не меняется никак. Сделайте выход по кнопке.
    while (digitalRead(5)) {
     
  8. ejik_off

    ejik_off Нуб

    тогда цикл будет работать пока кнопка в нажатом состоянии.
     
  9. ejik_off

    ejik_off Нуб

    изначально 0, после нажатия на кнопку в переменную записывается 1 если butt_flag=0 или 0 если butt_flag=1
    Но при попадание в цикл кнопка больше кнопка больше не работает
     
  10. Daniil

    Daniil Гуру

    Ну так? В цикле, чтобы выйти из цикла, чему равна эта переменная, а чему она равна у вас?
    Из-за того, что у вас кнопка без фиксации, то вам нужно городить костыль.
    1. приобрести кнопку с фиксацией
    2. реализовывать обработку нажатой клавиши по-другому.
    Нужно засечь момент когда кнопку нажали, когда отпустили, убедиться, что это не ложное срабатывание и запустить процедуру мигания светодиодами, как в решении по ссылке.
     
    Последнее редактирование: 13 май 2018
  11. Limoney

    Limoney Гик

    смотрите внимательнее
    Код (C++):
    butt_flag = 1;
      while ([B]butt_flag == 1[/B]){
      digitalWrite(r, HIGH); //включаем красный
      delay(500); //ждем 500 Мс
      digitalWrite(r, LOW); //выключаем красный
      digitalWrite(b, HIGH); //включаем синий
      delay(500); //ждем 500 Мс
      digitalWrite(b, LOW); //выключаем синий
      }
     
  12. ostrov

    ostrov Гуру

    Нет, он всегда будет работать. Внутри цикла кнопка не отслеживается.
     
  13. ejik_off

    ejik_off Нуб

    Вот про это и вопрос, как правильно отследить статус кнопки?
     
  14. Daniil

    Daniil Гуру

    Чем не нравится вариант, что я описал выше?
     
  15. ostrov

    ostrov Гуру

    Я написал выше как. Заменить одну строку.
     
    Последнее редактирование: 13 май 2018
  16. ejik_off

    ejik_off Нуб

    Вы имеет ввиду эту часть скетча?
    Код (C++):
    bool newState = digitalRead(BUTTON_PIN);       //

       if(newState == LOW && oldState == HIGH)   //
    {
           delay(20);                               //
        newState = digitalRead(BUTTON_PIN);         //

       if(newState == LOW)
     
  17. ejik_off

    ejik_off Нуб

    Можно пример. Я ни как не пойму как правильно делать проверку, если значения butt_flag меняю внутри цикла то светодиод не реагирует.
    while (butt_flag == 1){
    butt_flag = 1;
    digitalWrite(r, HIGH); //включаем красный
    delay(500); //ждем 500 Мс
    digitalWrite(r, LOW); //выключаем красный
    digitalWrite(b, HIGH); //включаем синий
    delay(500); //ждем 500 Мс
    digitalWrite(b, LOW); //выключаем синий

    }
     
  18. Limoney

    Limoney Гик

  19. ostrov

    ostrov Гуру

    Тогда зачем цикл?

    Автор определись что надо, если мигать пока кнопка нажата, то замени идну строку с while на ту что я написал выше.
     
  20. Daniil

    Daniil Гуру

    отчасти)
    но мы тут подходим, к тому, что вам не нужен ваш цикл (который сейчас бесконечен). И делать обработку нажатий несколько иначе.
    засечь нажатие
    выбрать режим светодиодов
    включить светодиоды в соответствии режиму
    т.к. они у вас мигают И(!) надо ждать следующего нажатия, то вам необходимо мигать светодиодами без delay