Кнопочный переключатель.

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

  1. yoko

    yoko Нуб

    Камрады! Помогите с 10 экспериментом!
    код:
    #define BUTTON_PIN 3
    #define LED_PIN 13
    boolean buttonWasUp = true;
    boolean ledEnabled = false;
    void setup()
    {
    pinMode(LED_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    }
    void loop()
    {
    // сначала понимаем, отпущена ли кнопка прямо сейчас...
    boolean buttonIsUp = digitalRead(BUTTON_PIN);

    // ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
    if (buttonWasUp && !buttonIsUp) {
    delay(10);
    buttonIsUp = digitalRead(BUTTON_PIN);
    if (!buttonIsUp) {
    ledEnabled = !ledEnabled;
    digitalWrite(LED_PIN, ledEnabled);
    }
    }
    buttonWasUp = buttonIsUp;
    }

    С кодом и его логикой разобрался. А вот с заданием:
    1. Измените код так, чтобы светодиод переключался только после отпускания кнопки.
    Никак не получается. Пробовал различные варианты, связанные с последним этапом
    if (!buttonIsUp) {
    ledEnabled = !ledEnabled;
    digitalWrite(LED_PIN, ledEnabled);
    Но ничего не выходит, не понимаю какая должна быть логика.
     
  2. DrProg

    DrProg Вечный нерд

    Код (Text):
    if (!buttonIsUp) {
    while(digitalRead(BUTTON_PIN));
    ledEnabled = !ledEnabled;
    digitalWrite(LED_PIN, ledEnabled);
    }
    или
    Код (Text):
    if (!buttonIsUp) {
    while(!digitalRead(BUTTON_PIN));
    ledEnabled = !ledEnabled;
    digitalWrite(LED_PIN, ledEnabled);
    }
    не помню как та кнопка на LOW или на HIGH нажатой считается.
     
    ИгорьК нравится это.
  3. geher

    geher Гуру

    Если пин INPUT_PULLUP, то при отпущенной кнопке на пине HIGH, соответственно, при нажатой должно быть LOW.
    Следовательно, после нажатия надо ждать, пока LOW, т.е. второй вариант - ждеи, пока нажатую кнопку отпустят.

    Можно сделать и по другому: просто полностью инвертировать логику и сразу ждать не нажатия на кнопку, а отпускания.
    Код (Text):

    void loop()
    {
        // сначала понимаем, отпущена ли кнопка прямо сейчас...
        boolean buttonIsUp = digitalRead(BUTTON_PIN);

        // ...если «кнопка была (не отпущена) нажата и (&&) не нажата (отпущена) сейчас»...
        if (!buttonWasUp && buttonIsUp) {
            delay(10);
            buttonIsUp = digitalRead(BUTTON_PIN);
            if (buttonIsUp) {
                 ledEnabled = !ledEnabled;
                 digitalWrite(LED_PIN, ledEnabled);
            }
        }
        buttonWasUp = buttonIsUp;
    }
     
     
  4. yoko

    yoko Нуб

    Вот, ждать пока нажатую кнопку отпустят. Каким образом? Такой вариант:
    buttonIsUp = digitalRead(BUTTON_PIN);
    if (!buttonIsUp) {
    delay (buttonIsUp);
    ledEnabled = !ledEnabled;
    digitalWrite(LED_PIN, ledEnabled);

    Не катит. А другие варианты в голову не приходят.
     
  5. geher

    geher Гуру

    Так DrProg предлагал же:
    Код (Text):

    if (!buttonIsUp) {
       while(!digitalRead(BUTTON_PIN));
       ledEnabled = !ledEnabled;
       digitalWrite(LED_PIN, ledEnabled);
    }
     
    Вставка строчки


    while(!digitalRead(BUTTON_PIN));

    в самое начало кода обработки факта нажатия кнопки вызывает задержку этой самой обработки до тех пор, пока кнопку не отпустят.

    А
    delay (buttonIsUp);
    бессмысленно, поскольку delay принимает параметром задержку в миллисекундах, а buttonIsUp - это по логике программы всего лишь индикатор состояния кнопки - HIGH - отпущена, LOW - нажата.
     
    Последнее редактирование: 6 сен 2015
  6. DrProg

    DrProg Вечный нерд

    delay (buttonIsUp); задержит код на 1 или 0мс. :p
     
    ИгорьК нравится это.
  7. yoko

    yoko Нуб

    Спасибо! Очень жаль, что к этим заданиям не приложено решение и если не знаешь как решить задачу, приходится двигаться дальше. Вот и следующее задание:
    1. Добавьте в схему еще одну кнопку и доработайте код, чтобы светодиод зажигался только при нажатии обеих кнопок.
    Какая тут должна быть логика?
     
  8. Tomasina

    Tomasina Сушитель лампочек Модератор

    эм, а что сложного?
    Код (Text):
    if( digitalRead(BUTTON1_PIN) && digitalRead(BUTTON2_PIN) ) digitalWrite(LED_PIN, HIGH);
    else digitalWrite(LED_PIN, LOW);
    либо так:
    Код (Text):
    digitalWrite(LED_PIN, (digitalRead(BUTTON1_PIN) && digitalRead(BUTTON2_PIN)) ? HIGH: LOW);
     
  9. West

    West Нуб

    Держите
    if(!buttonIsUp){
    while(!buttonIsUp) buttonIsUp = digitalRead(BUTTON_PIN);
    if (buttonIsUp){
    ledEnabled = !ledEnabled;
    digitalWrite(LED_PIN, ledEnabled);
    }
    }
    }
    // запоминаем последнее состояние кнопки для новой итерации
    buttonWasUp = buttonIsUp;
    }
     
  10. Нужно реализовать код по другому в этом эксперименте, т.к. команду "while" мы еще не изучали в этом курсе

    Тоже столкнулся с трудностями в этом эксперименте с дополнительными заданиями, решить это самостоятельно пока не могу.

    "Задания для самостоятельного решения
    1. Измените код так, чтобы светодиод переключался только после отпускания кнопки.
    2. Добавьте в схему еще одну кнопку и доработайте код, чтобы светодиод зажигался только при нажатии обеих кнопок."
     
    Ival-l нравится это.
  11. хочется задавать вопрос про ожидание в основном цикле ... это нормально, что основной цикл без delay ждет отпускания клавиши ? Можно ли ожидания отпускания использовать прерывание ?

    просвятите, многоопытные, чем код

    Код (C++):
    while(!digitalRead(BUTTON_PIN));
    лучше такого ?

    Код (C++):
    while(!digitalRead(BUTTON_PIN)){
    delay(50);
    }
    я видел в примерах и с задержкой и без нее, кто как ожидание пишет ?
     
  12. b707

    b707 Гуру

    Андрей Ипатов - оба кода одинаково плохие и в реальных программах их лучше не использовать. Плохи они тем, что программа у вас "зависает" в этих while циклах, пока удерживается кнопка. При попытке делать в программе что-то еще, кроме работы с кнопками, такой код создаст большие проблемы.
     
    Последнее редактирование: 4 дек 2017
    Андрей Ипатов нравится это.