И кнопка, и цифровой выход на одном пине

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Salk, 25 янв 2015.

  1. Salk

    Salk Гик

    Необходимо, задействовав всего один пин Arduino, управлять реле, как с ИК-пульта, так и с кнопки. Но при этом, свободного пина под кнопку нет, поэтому в голову взбрела такая идея:
    реле.jpg
    Суть:
    На кнопку подаётся +5 В от arduino, которые, при нажатии кнопки, должны коммутировать транзистор (реле включится).
    Когда кнопка разжата, мы можем управлять реле с пульта, т.е. управлять реле, как обычно.

    Так вот вопрос, возможно ли такая реализация? Скетч примерно ясен, в нем должен постоянно прослушиваться (digitalRead) пин реле и если пришли +5 В, нам нельзя управлять с ИК-пульта, т.к. реле уже включено, но если +5 В нет, мы можем управлять с пульта. Для этого придется постоянно переконфигурировать пин реле, меняя "pinMode, INPUT" для прослушивания +5 В и "pinMode, OUTPUT" для управления реле с пульта.
    Но меня смущает аппаратная реализация и по скетчу есть пара вопросов.
    Жду советов и мыслей :)
    Скетч пока такой:
    Код (Text):
    #include <IRremote.h>
    int RECV_PIN = 11; //пин подключения IR приёмника
    int RELAY_PIN = 1; //пин подключения реле

    IRrecv irrecv(RECV_PIN);
    decode_results results;
    bool LampState = false;

    void setup()
    {
      pinMode(RELAY_PIN,INPUT);
      irrecv.enableIRIn(); // Включаем ресивер
    }

    void loop()
    {
      pinMode(RELAY_PIN,INPUT); // конфигурируем на вход, для прослушки
      if (digitalRead(RELAY_PIN) == HIGH) // Кнопка нажата
      {
      }
      else // иначе кнопка разжата
      {
        if (irrecv.decode(&results)) // управляем с пульта
        {
          if (results.value == 524543) //Код кнопки реле
          {
            LampState = !LampState;
            if (LampState)
            {
              pinMode(RELAY_PIN,OUTPUT); // конфигурируем на выход
              digitalWrite(RELAY_PIN,HIGH);
            }
            else
            {
              pinMode(RELAY_PIN,OUTPUT);
              digitalWrite(RELAY_PIN,LOW);
            }
          }
          irrecv.resume(); // Получаем следующее значение
        }
      }
    }
     
  2. XCB

    XCB Гик

    Прям так как нарисовано мне кажется делать не стоит. Если на выводе будет низкий уровень и реле выключено, нажав кнопку мне кажется рискуете сжечь ножку.
     
  3. Salk

    Salk Гик

    Я думал об этом. Но pinMode, OUTPUT будет меняться только в момент, если придет сигнал с пульта (чтобы включить реле). Во всем остальном случае, пин будет сконфигурирован, как INPUT, т.е. пин будет настроен на вход всегда, кроме когда приходит сигнал с пульта. Или все таки я что-то упускаю?
    Тогда как можно усовершенствовать схему и вообще возможна такая задумка? Или без дополнительного свободного пина под кнопку не обойтись?
     
  4. geher

    geher Гуру

    Вопрос (не подумавши, исключительно навскидку). А если применить такой же метод, как при использовании двух источников питания?
    К базе два диода (если сопротивление обычных слишком велико, то Шоттки). Один от 5 В и кнопки, другой от пина. В результате сигнал с пина и сигнал с кнопки не будут мешать друг другу, и не придется что-то крутить в скетче. Для согласования по току и напряжению на базе транзистора докрутить резисторами.
     
  5. Salk

    Salk Гик

    Вы имеете ввиду так:
    1.jpg
    Да вариант. Но тогда, arduino никак не будет отслеживать нажатие кнопки. И запретить управление с ИК-пульта не получится. Что будет, если и кнопку нажать и с пульта включить. +5В и + 5В. Мне стыдно... в таком случае будет +10 В или около 0 В?

    Походу нет правильного решения с таким включением кнопки.
    А сдвиговые регистры умеют работать на вход и считывать значения?
    Мне по сути, нужно продублировать управление реле, сделать управление, как с пульта, так и с кнопки. Но вот лишнего пина нет :(
     
  6. Unixon

    Unixon Оракул Модератор

    Сделать можно, но не так. Вот правильная схема:
    bifunc_pin.png
     
  7. Salk

    Salk Гик

    Спасибо за схему на компараторе. Помогите рассчитать номиналы резисторов R1-R4, если взять питание +5 В, однополярное. По даташиту, можно питать даже от +2 В.

    Если взять условие VCC>VREF>VPIN>GND, то навскидку накидал номиналы резисторов такие:
    R1 = 2k, R2 = 1.5k, R3 =1k, R4 = 500 Oм. Получится: VCC(5V)>VREF(3.3V)>VPIN(2.85V)>GND. Подойдет?

    Немного непонятна сама логика работы схемы, разъясните пожалуйста :)
     
  8. Unixon

    Unixon Оракул Модератор

    Да, еще должно выполняться условие Vpin >= Vhigh, чтобы при разомкнутой кнопке МК устойчиво читал "1". Vref можно ближе к Vcc придвинуть. Резисторы смело берите из диапазона 10k-200k, не нужно лишний ток вхолостую гонять.
     
    Последнее редактирование: 27 янв 2015
  9. Unixon

    Unixon Оракул Модератор

    Схема работает на разнице в сопротивлении входа и выхода. Когда вывод МК находится в режиме входа, его сопротивление велико и напряжение на нем определяется обвязкой, т.е. в данном случае делителем на R1,R2 и кнопкой. Когда выход находится в режиме выхода, его сопротивление мало и напряжение определяется самим МК.

    Дальше делаем маленький фокус. Изначально у нас было всего два логических уровня "0"=GND=0V и "1"=Vcc=5V. Чтобы транзистор не видел "1" на выводе в режиме входа, но видел "1" в режиме выхода, сделаем еще один логический уровень "недоединица" Vref такой, чтобы МК видел его тоже как "1". Т.е. вместо одной логической "1" у нас будет две разных "1-in" и "1-out" - одна в режиме входа, другая в режиме выхода. Так вот, поскольку Vref > Vhigh, то МК их не будет отличать, а чтобы транзистор их не путал как раз и нужен компаратор, который будет воспринимать только "1-out"=Vcc, но не будет воспринимать "1-in"=Vref. Для транзистора "1-in" это все еще "0". Т.о. пока вывод МК в режиме входа, транзистор не будет срабатывать от подтяжки, но МК будет видеть нажатие кнопки сменой "1"->"0"->"1". Когда же вывод будет переведен в режим выхода, МК легко пересилит подтяжки (резисторы делителя) и выставит Vpin>Vref и вот эту "1-out" транзистор уже увидит, благодаря тому, что компаратор скачком переключит свой выход из GND в Vcc .

    В схему еще нужно добавить небольшой резистор типа 300R~1k между Vpin и собственно ножкой МК, чтобы защитить ее от случайного нажатия кнопки пока вывод в режиме выхода.
     
    Последнее редактирование: 27 янв 2015
  10. Salk

    Salk Гик

    Спасибо огромное, за разъяснение. У меня получились такие номиналы:
    R1 = 50k, R2 = 150k; R3 = 10k, R4 = 100k. И - VCC(5V) > VREF(4.5V) > VPIN(3.75V) > GND
    Думаю 3.75 В МК посчитает за "1". VREF ближе к VCC.

    Проверьте, пожалуйста, правильно ли я понял работу схемы: языком дилетанта - когда на прямом входе (VPIN) компаратора напряжение меньше, чем на инверсном (VREF), то на выходе компаратора "0". Если на прямом входе больше, чем на инверсном, то на выходе "1".
    Пин arduino изначально находится в режиме входа (INPUT; 3.75 В - "1"), и это напряжение (3.75 В) меньше, чем на инверсном входе компаратора (VREF), а значит на выходе "0". Как только мы нажимаем на кнопку, кнопка должна быть без фиксации ??? ("1" => "0" => "1"), arduino тут же шлет высокий уровень ("1") и уже VPIN становится больше, чем VREF и на выходе компаратора появляется "1" (т.е. включается реле). И это состояние длится до тех пор, пока мы снова не нажмем на кнопку ("1" => "0" => "1") и пин arduino снова не перейдет в режим входа. Либо, пока мы с пульта не сделаем тоже самое. Так? :)
    Защитный резистор (300-1k), думаю должен стоять после точки соединения R1, R2 и пина arduino.
     
  11. Unixon

    Unixon Оракул Модератор

    Можно примерно считать, что Vhigh ~ 0.8Vcc, 3.75V уже сработает нормально. Номиналы ОК.

    Обычная тактовая кнопка. Впрочем, это не имеет никакого значения.

    В остальном вроде бы все верно пересказали...
     
  12. Unixon

    Unixon Оракул Модератор

    Кстати, тут с выключением реле будет засада. После того, как МК переключит вывод в режим выхода, он не сможет больше считать состояние кнопки до тех пор, пока не переключит вывод обратно в режим входа. Но как только вывод переключится в режим входа, реле тут же отключится, поскольку Vpin изменится от Vcc>Vref к Vin<Vref.
     
  13. Salk

    Salk Гик

    Да.. А если очень быстро менять состояния вход-выхода, т.е. постоянно с большой скоростью проверять нажатие кнопки. А для сглаживания работы реле, поставить электролит. Или вообще тупиковая затея?
     
  14. altex

    altex Гик

    А разве в этой схеме не будет проблемы, если нажать на кнопку, когда на выходе пина будет логическая единица?
     
  15. Unixon

    Unixon Оракул Модератор

    Там еще резистор нужно добавить, про это я написал.
    А так - да, кнопка отключит реле и ее состояние будет неизвестно до переключения вывода на вход.
     
  16. Unixon

    Unixon Оракул Модератор

    Проще тогда контроллер пожирнее взять.
     
  17. Salk

    Salk Гик

    Если я поставлю защитный резистор (1 k) между соединением R1, R2 и пином arduino, не рискую ли я его сжечь?
    Компаратор собираюсь приобрести и поставить эксперимент.
    Набросал скетч, основанный на постоянном считывании состояния пина (INPUT) и "ловли" момента, когда нажали кнопку. Кнопка должна быть без фиксации.
    Код (Text):
    #include <IRremote.h>
    int RECV_PIN = 11; // пин подключения IR приёмника
    int RELAY_PIN = 3; // пин подключения реле, обязательно к ШИМ

    IRrecv irrecv(RECV_PIN);
    decode_results results;
    bool LampState = false;

    int STATE; // текущее состояние пина
    int BUTTON; // счетчик нажатия кнопки

    void setup()
    {
      pinMode(RELAY_PIN,INPUT);
      irrecv.enableIRIn(); // Включаем ресивер
      Serial.begin(9600);
    }

    void loop()
    {
      // необходимо использовать кнопку без фиксации
      pinMode(RELAY_PIN, INPUT); // постоянно проверяем состояние пина
      STATE = digitalRead(RELAY_PIN); // проверяем состояние пина и записываем в переменную
      if (STATE == HIGH) // кнопка не нажата
      {
        // это значит, что мы один раз уже нажали кнопку и нам необходимо удержать HIGH уровень
        if (BUTTON == 1)
        {
          pinMode(RELAY_PIN, OUTPUT); // выключим реле
          digitalWrite(RELAY_PIN, HIGH);
        }
        else // это означает, что мы нажали второй раз на кнопку, нам необходимо выключить реле
        {
          pinMode(RELAY_PIN, OUTPUT); // выключим реле
          digitalWrite(RELAY_PIN, LOW);
          BUTTON = 0; // сбрасываем счетчик
        }
        Serial.print("NO PUSH");
        if (irrecv.decode(&results))
        {
          if (results.value == 524543) // можем вкл/выкл с пульта
          {
            LampState = !LampState;
            if (LampState)
            {
              pinMode(RELAY_PIN, OUTPUT);
              digitalWrite(RELAY_PIN,HIGH);
            }
            else
            {
              pinMode(RELAY_PIN, OUTPUT);
              digitalWrite(RELAY_PIN,LOW);
            }
          }
          irrecv.resume(); // Получаем следующее значение
        }
      }
      else // Иначе кнопку нажали, т.е. "поймали" LOW
      {
        BUTTON = BUTTON + 1; // если поймали момент нажатия кнопки (LOW)
        Serial.print("ON PUSH");
        pinMode(RELAY_PIN, OUTPUT);
        digitalWrite(RELAY_PIN,HIGH);
      }
      delay(100); // скорость проверки состояния
    }
    Как то так...
     
  18. Unixon

    Unixon Оракул Модератор

    Сжечь что и по какой причине?
     
  19. Salk

    Salk Гик

    Простите, что пропал.
    Сегодня приобрел компаратор LM339 и начал ставить опыты.
    Да, глупый вопрос :)

    Собрал схему, с расчётными номиналами, не забыв про резистор 1 кОм к пину arduino, но компаратор не захотел работать, проверил два из четырех (их четыре в одном корпусе). Питал я его от +5 В Arduino однополярным питанием, на выходе "лог. 1" или хоть какого-то напряжения получить не удалось. При том номиналы резисторов перебирал. Даже просто напрямую повесил на VPin +5 В, а на ARef +2.5 В делителем по 10 кОм, на выходе ничего.
    Видимо придется питать от ±15 - 18 В, интересно при таком питании, "лог. 1" на выходе будет равна +5 В ?
    Или есть подобные микросхемы с питанием +5 В ?

    Скетч, хоть более менее, рабочий: нажатие кнопки (LOW) "ловит", и удерживает HIGH уровень до следующего нажатия кнопки, правда главное не передержать кнопку, иначе счетчик "накрутит" и сбросится снова в 0 (так же зависит от скорости обновления "delay(*))". Но доработкой скетча займусь чуть позже.
    Ещё момент, когда arduino в режиме INPUT напряжение на VPIN около 0 В, а не 3.75 В, т.к. все уходит на землю через arduino, но тут все равно VPIN < VREF и на выходе должен быть "0". Это потом, когда arduino "поймает" кнопку и перейдет в режим OUTPUT на VPIN будет +5 В, тогда станет VPIN > VREF на выходе должна быть "1", но, пока, не в моем случае ... :)
    Я же все делаю правильно ?
     
  20. Unixon

    Unixon Оракул Модератор

    Не уверен, что-то у вас не так.
    С питанием у компаратора все нормально, можно питать 0,+5V. Подключили точно правильно?

    Вот этого быть не должно, сопротивление входа много больше сопротивления плечей делителя, он не может их пересилить.