Долгое нажатие клавиши

Тема в разделе "Arduino & Shields", создана пользователем ZVEN, 3 май 2017.

  1. mcureenab

    mcureenab Гуру

    https://www.arduino.cc/en/Reference/digitalRead
    Такой код будет портируемым.
    Код (C++):
    (HIGH == digitalRead(pin))^(!high)
     
  2. mcureenab

    mcureenab Гуру

    Тут не для всякого приложения это возможно. Ведь сначала сработает удержание <= 2 сек, потом <= 5 сек, потом 5 сек <.
    На практике удержание кнопки без какой либо обратной связи не будет удобным.
    Например, после каждого порога времени можно подавать сигнал, а когда кнопка отпущена, выполнить требуемое действие.
     
  3. ostrov

    ostrov Гуру

    Вариантов много, все зависит от задачи. В данном примере время нажатия определяется после отпускания. Если же нужно иное, то делать следует иначе.
     
  4. qwone

    qwone Гик

    А еще, не все могут написать длинные программы и не запутаться в них и их работе. А некоторые "бойцы" путаются даже не начав писать.И тогда появляются подобные темы. Но даже если им кинуть рабочий скетч, то нет гарантии, что они и в нем разбирутся. Вот и выходит, что длиное нажатие - не всем новичкам по зубам, не смотря что просто выглядит.
     
    ostrov нравится это.
  5. ostrov

    ostrov Гуру

    Давно известный факт. В том числе и поэтому и не люблю передавать открытый код, обязательно какой нибудь умник решит его улучшить и все сломает.
     
  6. ZVEN

    ZVEN Нерд

    Я написал простой код, только не пойму почему он не работает.
    Помогите разобраться
    Код (C++):

    Данный код в процедуре Loop юзается
    unsigned long timeStart = millis();
      if (digitalRead(BUTTON) == HIGH)
      {
        //Нажали кнопку
        if ((timeStart + 4000) < millis())
        {
          //Если нажата 4 сек
          Serial.println("5 sec");
          delay(10000);
        }
        else
        {
          Serial.println("Button activate");
          int tInt = round(t);
          disp.display(tInt);
          delay(1000);
        }
      }
      else
      {
      //Тут если кнопка не нажата ни разу
      }
     
  7. mcureenab

    mcureenab Гуру

    timeStart = millis();
    ...
    (timeStart +4000)< millis()

    думаете это когда то сработает?
     
  8. ostrov

    ostrov Гуру

    Надо вам разобраться как работает millis() и заодно избавиться от delay()
     
  9. Eragon

    Eragon Нерд

    Вам нужна только задержка включения? Или необходимо по длительному нажатию кнопки выполнять одно действие, а по короткому другое?
     
  10. ZVEN

    ZVEN Нерд

    По длительному нажатию, допустим 4 секунды, выполнять одно действие, а по одному короткому нажатию - другое
     
  11. ZVEN

    ZVEN Нерд

    Почему избавиться от delay? Мне оно нужно там.
     
  12. ostrov

    ostrov Гуру

    А если МК должен делать что то еще кроме ожидания кнопки? Или это у вас единственный проект в жизни?
     
  13. ostrov

    ostrov Гуру

    Вот тут уточнить, после удержания 4 сек начинается другое действие или после отпускания кнопки дольше 4х сек? Если второе, то выше я дал готовый код, отмотайте уже.
     
  14. ZVEN

    ZVEN Нерд

    Первое
     
  15. qwone

    qwone Гик

    Считайте millis() обычными часами, только считающие миллисекунды. Фиксируйте время нажатия (пусть будет past) . теперь время удержания это (miilis()-past). но вам надо сделать время однократно а не делать постоянно. так что нужен флаг .
    Итого выходит:
    Код (C++):
    void setup() {


    }

    bool flag = 0;
    void loop() {
      static uint32_t past = 0;
      a_old = a;
      a = digitalRead(btn_pin);// 0 уровень наж кнопки
      if (a_old && !a) {
        past = millis();
        flag = 1;
      }
      if (flag && millis() - past >= time_4s && ! a) {
        flag = 0;
        // сделать то что надо при длинном нажатии
      }
    }
     
  16. ZVEN

    ZVEN Нерд

    Спасибо, вечером проверю
     
  17. ostrov

    ostrov Гуру

    Если первое то еще проще. Вы попробуйте разобраться немного как оно работает. Тут принято подсказывать, а готовые решения вам с удовольствием сделают в "Закажу проект".
     
  18. ZVEN

    ZVEN Нерд

    Блин закинул код и чет не робит.
    Вот так:
    Код (C++):
    static uint32_t past = 0;
      button_old = button;
      button = digitalRead(BUTTON);

      if (button_old && !button)
      {
        past = millis();
        check = true;
       
        Serial.println("Button activate");
        int tInt = round(t);
        disp.display(tInt);
        delay(1000);
       
      }
      else if (check && millis() - past >= 4000 && !button)
      {
        check = false;
       
        Serial.println("10 sec");
        delay(10000);
      }
      else
      {
        Serial.println("Button not activate");
        digitalWrite(water_sensor_power, HIGH);                                     // Включаем питание на пине, к которому подключен плюс датчика
        delay(10);                                                                     // Время, необходимое датчику, чтобы включиться и замерить показания
        water_value = analogRead(water_sensor);                              // Считываем показания датчика YL-69 (от 0 до 1023, где 1023 - сухо)
        digitalWrite(water_sensor_power, LOW);                                      // Отключаем питание на пине, к которому подключен плюс датчика

        water_value_percent = map(water_value,very_water_value,1023,100,0);  // Переводим показания датчика YL-69 в проценты
        disp.display(water_value_percent);  
      }
    А переменные объявил вышел setup(), пробовал задавать button_old и тру и фолс, но без разницы.
    Код (C++):
    bool button;
    bool button_old = true;
     
  19. qwone

    qwone Гик

    у вас delay() фетиш что ли?
     
  20. ZVEN

    ZVEN Нерд

    Мне он там нужен, все не просто так.
    Во вторых с помощью задержки проверяю длительное нажатие.