Двойной клик. Урок 9. Ардуино

Двойной клик по кнопке
Разные кнопки и Ардуино
Разные кнопки и Ардуино

Привет! Как вы считаете, много ли функций может выполнять одна кнопка? На самом деле, очень много. Кажется даже, столько, сколько нужно. Давайте посмотрим, как можно запрограммировать кнопку более функционально и обработаем на Ардуино двойной клик по кнопке.

В предыдущих уроках мы уже рассматривали подключение кнопок и подавление дребезга. Сейчас мы модифицируем функцию подавления дребезга так, чтобы подсчитывать количество кликов по кнопке. Так что, посмотрите предыдущие уроки, если вы пропустили их или уже забыли.

Дребезг кнопки. Урок 2.3. Ардуино

Чтобы выполнить этот урок нам понадобятся.

  • Ардуино UNO
  • Макетная плата
  • Перемычки
  • Резистор номиналом 220 Ом
  • Кнопка
  • Кабель USB

Схема и программа

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

Подключение кнопки через стягивающий резистор
Подключение кнопки через стягивающий резистор

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

Задача на сегодня будет такой. Запрограммировать Ардуино на обработку нажатий кнопки. Бесспорно. нажатия могут быть разными.

  • Простое короткое нажатие на кнопку
  • Двойное нажатие на кнопку
  • Неопределенное количество нажатий

Логично будет объединить все пункты задачи и разработать логику программы так, чтобы она подсчитывала количество кликов и выполняла определенные действия в зависимости от него. В том числе и двойной клик и тройной клик.

Двойной клик

Как и в функции debounce нам необходимо подсчитывать время между нажатием на кнопку, чтобы определить количество кликов.

Для этого внутри цикла loop() проверяем состояние контакта Ардуино, на котором подключена кнопка. Если состояние изменилось, то на переменную счетчика повесим таймер millis()

boolean reading = digitalRead(BUTTON_PIN);

if (reading && !lastReading){
    onTime = millis();

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

  if (!reading && lastReading){
    if (((millis() - onTime) > bounceTime)){
      if ((millis() - lastSwitchTime) >= doubleTime){
        lastSwitchTime = millis();
        buttonSingle = true;
        i=1;
      } else {
        i++;
        lastSwitchTime = millis();
        buttonSingle = false;
        buttonMulti = true;
      }
    }

Счетчик i увеличивается каждый раз, когда клик по кнопке происходит быстрее, чем установленный лимит времени. Переменную этого лимита также можно настроить вручную.

Не забудем обновить значение предыдущего состояния кнопки в конце цикла.

lastReading = reading;

Мы определили, было ли нажатие на кнопку, а в счетчике i записали количество нажатий. Если эти условия выполнялись, то соответствующие переменные находятся в состоянии true. Обработаем их.

  if (buttonSingle && (millis() - lastSwitchTime) > doubleTime){
    isButtonSingle();
  }
  if (buttonMulti && (millis() - lastSwitchTime) > doubleTime){
    isButtonMulti(i);
  }

Таким образом мы вызываем соответствующие функции. И передаем в функцию мультиклика количество этих кликов по кнопке.

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

void isButtonSingle(){
    buttonMulti = false;
    buttonSingle = false;
    Serial.println(1);
}
void isButtonMulti( int count ){
    buttonSingle = false;
    buttonMulti = false;
    Serial.println(count);
}

Как видно из кода, в данном случае мы просто выводим счетчики в монитор последовательного порта. Но не забудьте сбросить управляющие переменные на false, чтобы не испортить управление программой в следующем цикле.

А так же объявить переменные для первоначальной настройки программы.

Монитор последовательного порта и нажатия на кнопку
Монитор последовательного порта и нажатия на кнопку

Полный текст программы

#define BUTTON_PIN 2

int bounceTime = 10;          // задержка для подавления дребезга
int doubleTime = 500;         // время, в течение которого нажатия можно считать двойным
int i = 0;

boolean lastReading = false;  // флаг предыдущего состояния кнопки
boolean buttonSingle = false; // флаг состояния "краткое нажатие"
boolean buttonMulti = false; // флаг состояния "двойное нажатие"

long onTime = 0;              // переменная обработки временного интервала
long lastSwitchTime = 0;      // переменная времени предыдущего переключения состояния

void setup(){
  Serial.begin(9600);
}

void loop(){
  boolean reading = digitalRead(BUTTON_PIN);

  // проверка первичного нажатия
  if (reading && !lastReading){
    onTime = millis();
  }
  
  if (!reading && lastReading){
    if (((millis() - onTime) > bounceTime)){
      if ((millis() - lastSwitchTime) >= doubleTime){
        lastSwitchTime = millis();
        buttonSingle = true;
        i=1;
      } else {
        i++;
        lastSwitchTime = millis();
        buttonSingle = false;
        buttonMulti = true;
      }
    }
  }
  
  lastReading = reading;
  
  if (buttonSingle && (millis() - lastSwitchTime) > doubleTime){
    isButtonSingle();
  }
  if (buttonMulti && (millis() - lastSwitchTime) > doubleTime){
    isButtonMulti(i);
  }
}

void isButtonSingle(){
    buttonMulti = false;
    buttonSingle = false;
    Serial.println(1);
}
void isButtonMulti( int count ){
    buttonSingle = false;
    buttonMulti = false;
    Serial.println(count);
}

Заключение

Мы научились использовать кнопку подключенную к Ардуино для считывания двойного клика и вообще любого количество кликов. Теперь мы можем настроить управление любым устройством на Ардуино только лишь одной кнопкой. В следующий раз попробуем еще больше увеличить функционал и запрограммируем долгие нажатия с определением длительности нажатия кнопки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *