поочередное включение двух светодиодов одной кнопкой

Тема в разделе "Arduino & Shields", создана пользователем Толик Иванов, 14 июл 2015.

  1. Толик Иванов

    Толик Иванов Administrator Администратор

    как включить и как помигать - это понятно. посмотрел видеоурок, разобрался- все понял, все работает. но вот делаю так чтоб при первом нажатии на кнопку загорался светодиод 1, а при втором нажатии на эту же кнопку загорался светодиод 2. но как ни странно ничего не получается. то оба горят и не тухнут, то оба горят пока зажата кнопка. но как надо не получается никак. Может кто подскажет в чем дело? последнюю модификацию кода на которой я устал биться лбом выкладываю ниже.
    Код (Text):
    int ledPin1 = 13;
    int ledPin2 = 12;
    int switchPin = 7;                
    boolean val = 0;
    boolean lastButton = LOW;
    boolean currentButton = LOW;
    boolean ledOn = false;
    void setup()
    {
      pinMode(ledPin1, OUTPUT);    
      pinMode(ledPin2, OUTPUT);
      pinMode(switchPin, INPUT);    
    }
    boolean debounce (boolean last)
    {
      boolean current = digitalRead(switchPin);
      if (last != current)
      {
        delay (5);
        current = digitalRead(switchPin);
        }
        return current;
      }
    void loop()
    {
    if (digitalRead(switchPin) == HIGH && val == 0)
      {
        digitalWrite(ledPin1, HIGH);
        val=1;
      }

      if (digitalRead(switchPin) == HIGH && val == 1)
      {
        digitalWrite(ledPin1, LOW);  
        digitalWrite(ledPin2, HIGH);
      }
    }
     
  2. Deniss

    Deniss Гик

    принцип можно сделать такой:
    при нажатии на кнопку переменная допустим Х увеличивает свое значение на 1
    далее идет проверка если
    если х = 0 то ничего не горит
    если х = 1 то горит 1
    если х = 2 то горит 2
    если х = 3 то х =0 (ничего не горит)
     
  3. Толик Иванов

    Толик Иванов Administrator Администратор

    сейчас попробую
    спасибо!
     
  4. Толик Иванов

    Толик Иванов Administrator Администратор

    намесил я следующего, но при замыкании контактов кнопки ничего не происходит вообще. чтото не так ...

    Код (Text):
    int ledPin1 = 13;
    int ledPin2 = 12;
    int switchPin = 7;                
    int val = 0;
    boolean lastButton = LOW;
    boolean currentButton = LOW;
    boolean ledOn = false;
    void setup()
    {
      pinMode(ledPin1, OUTPUT);    
      pinMode(ledPin2, OUTPUT);
      pinMode(switchPin, INPUT);    
    }
    boolean debounce (boolean last)
    {
      boolean current = digitalRead(switchPin);
      if (last != current)
      {
        delay (5);
        current = digitalRead(switchPin);
        }
        return current;
      }
    int functionLed (int val)
    {
      val= ++val;
      return val;
    }
     
    void loop()
    {
    if (digitalRead(switchPin) == HIGH)
      {
      int val= ++val;    // пробывал сюда подставить саму функцию functionLed  
      }                           //и передать в него переменную val , результат- ниче не загорается.

      if (val == 1)
      {
        digitalWrite(ledPin1, HIGH);
      }
      if (val == 2)
      {
        digitalWrite(ledPin2, HIGH);
      }
     
    }
     
  5. Deniss

    Deniss Гик

    Код (Text):

    int ledPin1 = 13;
    int ledPin2 = 12;
    int switchPin = 7;
    int val = 1;
    void setup()
    {
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin2, OUTPUT);
      pinMode(switchPin, INPUT);
    }


    void loop()
    {

    if (digitalRead(switchPin) == HIGH)
    {
      delay (10);
       if (digitalRead(switchPin) == HIGH)
       {
      val = ++val;
      if (val > 2) val = 1;
    }}

      if (val == 1)
      {
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 2)
      {
        digitalWrite(ledPin2, HIGH);
        digitalWrite(ledPin1, LOW);
      }

    }

     
     
  6. Толик Иванов

    Толик Иванов Administrator Администратор

    так так так
    спасибо!! уже чтото получается. попробую ща сделать с триггером шмидта стабильное включение кнопки апаратно не програмно
    а то не каждый раз срабатывает.
     
  7. Salk

    Salk Гик

    Минус Вашего кода в том, что он не стабилен. Val будет "накручиваться", пока кнопка зажата.

    Можно пойти таким путем:
    PHP:
    int ledPin1 = 13;
    int ledPin2 = 12;
    int switchPin = 7;

    int val;

    int state;
    int c;

    void setup()
    {
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin2, OUTPUT);
      pinMode(switchPin, INPUT);
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
    }

    void loop()
    {
      state = digitalRead(switchPin);

      if (state == HIGH && c == 0) // нажали кнопку
      {
        c = 1;
      }
      if (state == LOW && c == 1) // отпустили кнопку
      {
        val = ++val;
        if (val == 4)
        {
          val = 0;
        }
        c = 0;
      }

      if (val == 0) // выключаем светодиоды
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 1) // Если мы кнопку 1 раз нажали и отпустили
      {
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 2) // Если мы кнопку 2 раз нажали и отпустили
      {
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin2, HIGH);
      }
      if (val == 3) // Если мы кнопку 3 раз нажали и отпустили
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, HIGH);
      }
      delay(10);
    }
    Тут к переменной val прибавляется единица, только тогда когда мы кнопку отпустили, и больше не трогаем. Разумеется сама кнопка должна быть притянута к минусу Arduino через резистор 10 кОм, а 5V подаваться на пин 7, только тогда когда мы кнопку замыкаем (нажимаем).
    В данном коде, светодиоды буду загораться только после отпускания кнопки.
     
  8. Deniss

    Deniss Гик

    согласен не учел ;) можно сунуть еще в конце цикл while при нажатой кнопке ждать.... чтоб не париться
     
  9. Толик Иванов

    Толик Иванов Administrator Администратор

    попробывал с инвертирующим тригером шмидта и с кодом что предложил Salk. все работает по 4 нажатиям сначала 1 потом 1и2 потом 2 и потом ни один.
    сейчас попробую сделать чтоб было по первому нажатию только 1 а по второму только 2 и через секнду чтоб 2 тух.
     
  10. Толик Иванов

    Толик Иванов Administrator Администратор

    подправил немного код который подсказал Salk.
    Код (Text):
    int ledPin1 = 13;
    int ledPin2 = 12;
    int switchPin = 7;

    int val;

    int state;
    int c;

    void setup()
    {
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin2, OUTPUT);
      pinMode(switchPin, INPUT);
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
    }

    void loop()
    {
      state = digitalRead(switchPin);

      if (state == HIGH && c == 0) // нажали кнопку
      {
        c = 1;
      }
      if (state == LOW && c == 1) // отпустили кнопку
      {
        val = ++val;
        if (val == 3)
        {
          val = 0;
        }
        c = 0;
      }

      if (val == 0) // выключаем светодиоды
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 1) // Если мы кнопку 1 раз нажали и отпустили
      {
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 2) // Если мы кнопку 2 раз нажали и отпустили
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, HIGH);
      }
     
      delay(10);
     
    }

    теперь все работает верно вопрос в следующем , как сделать чтоб после того как загорелся второй LED, через к примеру одну секунду и он тух без дополнительного нажатия на кнопку.
    попробывал после всего кода внизу сделать delay (1000) вместо (10) и ниже прописать
    Код (Text):
    digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, LOW);
    но все сразу перестало работать и загоралось когда хотело и тухло так же или вообще не тухло....
     
  11. Толик Иванов

    Толик Иванов Administrator Администратор

    решил вопрос и с тем чтоб светодиод самостоятельно тух и без третьего нажатия на кнопку
    Код (Text):
     if (val == 2) // Если мы кнопку 2 раз нажали и отпустили
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, HIGH);
        delay(500);
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, LOW);
        val = 0;
        c = 0;
      }
     
      delay(10);
    теперь все гаснет и работает только на двух нажатиях
    первое нажатие первый светодиод
    второе нажатие - второй светодиод
    потом пол секунды и все возвращается к началу.
     
  12. Толик Иванов

    Толик Иванов Administrator Администратор

    теперь вопросики по сложнее, как сделать так чтоб после первого нажатия на кнопку и при отсутствии второго нажатия на кнопку, на протяжении 2х секунд к примеру, переменные val и c принимали значение 0?
    тоесть чтоб при отрабатывании только одного нажатия, программа понимала что чтото пошло не так и переходила в изначальное положение
     
  13. Salk

    Salk Гик

    с помощью счетчика - millis()
    Если после двух секунд у нас нет значения val == 2, то выключаем светодиоды:
    PHP:
    int ledPin1 = 13;
    int ledPin2 = 12;
    int switchPin = 7;

    int val;
    int state;
    int c;

    #define TIME 2000 // 2 сек
    unsigned long int time;

    void setup()
    {
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin2, OUTPUT);
      pinMode(switchPin, INPUT);
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
    }

    void loop()
    {
      state = digitalRead(switchPin);

      if (state == HIGH && c == 0) // нажали кнопку
      {
        c = 1;
      }
      if (state == LOW && c == 1) // отпустили кнопку
      {
        val = ++val;
        if (val == 3)
        {
          val = 0;
        }
        c = 0;
        time = millis(); // обнуляем счетчик
      }

      if (val == 0) // выключаем светодиоды
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 1) // Если мы кнопку 1 раз нажали и отпустили
      {
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin2, LOW);
      }
      if (val == 2) // Если мы кнопку 2 раз нажали и отпустили
      {
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, HIGH);
      }

    // Если после двух секунд мы не нажали второй раз на кнопку, то возвращаемся в дефолт - тушим светодиоды
      if (millis() - time > TIME)
      {
        if (val != 2)
        {
          val = 0;
        }
      }
      delay(10);
    }
    Переменную "с" нам не нужно обнулять, она и так обнуляется, после того когда мы отпускаем кнопку и нужна только для этого.
     
    teach me нравится это.
  14. Толик Иванов

    Толик Иванов Administrator Администратор

    спасибо!!! Все работает! На этом пожалуй на сегодня все!
     
  15. SergNSK

    SergNSK Нуб

    Всем привет. А схему подключения можно?? То есть кнопка к + и к контакту № 7 .