Долгое нажатие на кнопку. Урок 10. Ардуино

Долгое нажатие на кнопку
Разные кнопки и Ардуино
Разные кнопки и Ардуино

Привет! Что еще можно сделать с кнопкой? Можно нажать, можно отпустить. Можно нажать много раз. А можно нажать и удерживать. Давайте запрограммируем долгое нажатие на кнопку и разные сценарии в зависимости от времени нажатия.

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

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

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

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

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

Опять подключим кнопку к Ардуино по уже знакомой схеме. Используем стягивающий резистор. Но давайте сегодня добавим RGB светодиод и запрограммируем управление им.

Принципиальная схема подключения кнопки и RGB светодиода
Принципиальная схема подключения кнопки и RGB светодиода

Прежде всего, для функции мультиклика напишем новую функцию rgbMulti. Пускай она запрограммирует светодиод мигать столько раз, сколько раз была нажата кнопка.

Для одиночного нажатия сделаем функцию rgbRand Она будет включать случайный цвет на светодиоде.

Сделаем так, чтобы функция, которая обработает долгое нажатие будет создавать сияние светодиода разными цветами. И, наконец, если длительность клика будет больше 5 секунд, светодиод будет выключаться.

Долгое нажатие

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

  if (reading && lastReading){
    if ((millis() - onTime) > holdTime){
      holdTimeSum = (millis() - onTime);
      buttonHold = true;
    }
  }

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

    if (buttonHold){
      isButtonHold( holdTimeSum );
    }

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

Теперь осталось только добавить обработчик и объявить необходимые переменные.

int holdTimeSum = 0;  
boolean buttonHold = false;

void isButtonHold( int count ){
    buttonHold = false;
    buttonMulti = false;
    Serial.println(count);
}

RGB светодиод

Несомненно, добавим в программу нужные для управления светодиодом переменные и функции. Настроим контакты Ардуино на вывод.

int RLED = 9;
int GLED = 10;
int BLED = 11;

pinMode(RLED, OUTPUT);
pinMode(GLED, OUTPUT);
pinMode(BLED, OUTPUT);

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

void rgbMulti( int count){
  int j;
  Serial.println("MULTI");
  Serial.println(count);
  for(j=1; j <= count; j++){
    analogWrite(RLED, 127);
    analogWrite(GLED, 127);
    analogWrite(BLED, 127);
    delay(500);
    analogWrite(RLED, 0);
    analogWrite(GLED, 0);
    analogWrite(BLED, 0);
    delay(500);
  }
}

void rgbRand(){
    Serial.println("RAND");
    analogWrite(RLED, random(127));
    analogWrite(GLED, random(127));
    analogWrite(BLED, random(127));  
}

void rgbShine(){
  int j;
  Serial.println("SHINE");
  for(j=0;j<=255;j++){
    analogWrite(RLED, random(0,j));
    analogWrite(GLED, random(0,j));
    analogWrite(BLED, random(0,j));
    delay(5);
  }
  for(j=255;j>=0;j--){
    analogWrite(RLED, random(0,j));
    analogWrite(GLED, random(0,j));
    analogWrite(BLED, random(0,j));
    delay(5);
  }   
}

void rgbOff(){
    Serial.println("OFF");
    analogWrite(RLED, 0);
    analogWrite(GLED, 0);
    analogWrite(BLED, 0);  
}

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

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

#define BUTTON_PIN 2

int RLED = 9;
int GLED = 10;
int BLED = 11;

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

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

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

void setup(){
  Serial.begin(9600);
  pinMode(RLED, OUTPUT);
  pinMode(GLED, OUTPUT);
  pinMode(BLED, OUTPUT);    
}

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

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

void isButtonSingle(){
    buttonMulti = false;
    buttonSingle = false;
    rgbRand();
}
void isButtonMulti( int count ){
    buttonSingle = false;
    buttonMulti = false;
    rgbMulti(count);
}

void isButtonHold( int count ){
    buttonHold = false;
    buttonMulti = false;
    if( count <= 5000 ){
      rgbShine();
    } else {
      rgbOff();
    }
}

void rgbMulti( int count){
  int j;
  Serial.println("MULTI");
  Serial.println(count);
  for(j=1; j <= count; j++){
    analogWrite(RLED, 127);
    analogWrite(GLED, 127);
    analogWrite(BLED, 127);
    delay(500);
    analogWrite(RLED, 0);
    analogWrite(GLED, 0);
    analogWrite(BLED, 0);
    delay(500);
  }
}

void rgbRand(){
    Serial.println("RAND");
    analogWrite(RLED, random(127));
    analogWrite(GLED, random(127));
    analogWrite(BLED, random(127));  
}

void rgbShine(){
  int j;
  Serial.println("SHINE");
  for(j=0;j<=255;j++){
    analogWrite(RLED, random(0,j));
    analogWrite(GLED, random(0,j));
    analogWrite(BLED, random(0,j));
    delay(5);
  }
  for(j=255;j>=0;j--){
    analogWrite(RLED, random(0,j));
    analogWrite(GLED, random(0,j));
    analogWrite(BLED, random(0,j));
    delay(5);
  }  
}

void rgbOff(){
    Serial.println("OFF");
    analogWrite(RLED, 0);
    analogWrite(GLED, 0);
    analogWrite(BLED, 0);  
}

Заключение

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

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

Ваш адрес email не будет опубликован.