Поговорим о клавиатурах. Часть 4 - Подавление дребезга контактов, корректная обработка нажатий кнопок.

03.09.2017 01:38

jazon



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

          Итак, начнем... Клавиатурный модуль(на фото ниже) уже был рассмотрен в одной из предыдущих статей, в этой статье мы вернули его в наш "Серый ящичек", в котором он был размещен ранее, кстати, это устройство мы тоже обозревали в одной из статей, называлась она "Проект Grey Box[Серая коробка] - Начало"

        А вот так выглядит данный клавиатурный модуль в уже готовом устройстве, "серый ящик" - это так называемая оболочка-контроллер, осталось только запрограммировать...

        Чтобы понять как влияет дребезг контактов на работу программы, был подготовлен простейший скетч для серого ящика. Это простейший калькулятор, при нажатии на любую из пронумерованных кнопок клавиатурного модуля, значение выводимое в монитор порта будет суммироваться со значением, которым пронумерована сама кнопка. При нажатии на кнопку '0', значение будет обнуляться. Что нам понадобится для эксперимента? Мы будем использовать наш серый ящик по полной программе, хехе, прошу прощения за невольный каламбур... А вам уважаемые любители ардуин, в общем то достаточно платы Arduino Uno(подойдет также Mega, Nano, ProMini и др.), вы можете активно использовать монитор порта из Arduino IDE(если нет под рукой LCD дисплея как у нас) и даже такую разработку как Serial Monitor Pro(бесплатная утилита для самых изысканных гурманов), ну и естественно понадобится сам клавиатурный модуль. Если его нет - можно использовать шилд LCD1602 KeyPad Shield, на его борту уже присутствует такой клавиатурный модуль на 5 кнопок. Небольшое уточнение - нижеследующий скетч адаптирован всё таки для монитора порта, для лучшего понимания нашими читателями. Итак, вы подключили кнопочный клавиатурный модуль к плате, тестируем нижеследующий скетч:  

Листинг №1. Простейший калькулятор. Попытка сложения чисел без подавления дребезга.
int button;
const int BUTTON_0 = 0;
const int BUTTON_1 = 1;
const int BUTTON_2 = 2;
const int BUTTON_3 = 3;
const int BUTTON_4 = 4;
const int BUTTON_5 = 5;
const int BUTTON_6 = 6;
const int BUTTON_7 = 7;
const int BUTTON_8 = 8;
const int BUTTON_9 = 9;
const int BUTTON_ENT = 10;
const int BUTTON_ESC = 11;
const int BUTTON_NONE = 12;

//Amount - переменная для наращивания суммируемого значения
int Amount = 0;
int currentButtonState, previousButtonState;

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

void loop() 
{
  //Сначала считать нажатие кнопки
  currentButtonState = getPressedButton();
  //Далее вызываем обработчик нажатия 
  ButtonEventProc(currentButtonState);
}

//Функция для получения кода нажатой кнопки
int getPressedButton()
{
  // считываем значения с аналогового входа(A0)
  int buttonValue = analogRead(0);  

  if(buttonValue < 480)
    return BUTTON_NONE;    
  else if(buttonValue < 500)
    return BUTTON_ESC;     
  else if(buttonValue < 525)
    return BUTTON_0;    
  else if(buttonValue < 551)
    return BUTTON_ENT; 
  else if(buttonValue < 582)
    return BUTTON_3;
  else if(buttonValue < 615)
    return BUTTON_6;
  else if(buttonValue < 652)
    return BUTTON_9;
  else if(buttonValue < 695)
    return BUTTON_2;
  else if(buttonValue < 744)
    return BUTTON_5;
  else if(buttonValue < 800)
    return BUTTON_8;
  else if(buttonValue < 865)
    return BUTTON_1;
  else if(buttonValue < 940)
    return BUTTON_4;
  else if(buttonValue < 1024)
    return BUTTON_7;
}

//Функция обработчик события нажатой кнопки
void ButtonEventProc(int analogValue)
{
  switch(analogValue)
  {
    case BUTTON_NONE: 
      //Serial.println();
      break;
    case BUTTON_0:
      Calculation(BUTTON_0);
      break;
  case BUTTON_1:
      Calculation(BUTTON_1);
      break;
  case BUTTON_2:
      Calculation(BUTTON_2);
      break;
  case BUTTON_3:
      Calculation(BUTTON_3);
      break;
  case BUTTON_4:
      Calculation(BUTTON_4);
      break;
  case BUTTON_5:
      Calculation(BUTTON_5);
      break;
  case BUTTON_6:
      Calculation(BUTTON_6);
      break;
  case BUTTON_7:
      Calculation(BUTTON_7);
      break;
  case BUTTON_8:
      Calculation(BUTTON_8);
      break;
  case BUTTON_9:
      Calculation(BUTTON_9);
      break;
  case BUTTON_ENT:
      Serial.println("Button ENT pressed...");
      break;
  case BUTTON_ESC:
      Serial.println("Button ESC pressed...");
      break;
  }
}

//Функция обработчик наращивания суммируемого значения
void Calculation(int numButton)
{
  if(numButton == 0)
  {
    Amount = 0;
    Serial.print("Amount = ");
    Serial.println(Amount);
  }
  else
  {
    Serial.print(Amount);
    Serial.print(" + ");
    Serial.print(numButton);
    Serial.print(" = ");
    Amount = Amount + numButton;
    Serial.println(Amount);
  }
}

        Скетч загружен в плату Arduino, и тест показывает что в мониторе порта при нажатии кнопок творится настоящий бардак(что и будет показано в видеоролике ниже). Пришло время Domestos с хлором решить эту проблему, небольшое изменение в главной функции loop() дадут нам искомый результат - подавление дребезга и фильтрация сигнала от устройства ввода, дают возможность остальной части кода корректно обрабатывать и суммировать значение приращения от нажатий кнопок. Приведём только измененный кусок кода в функции loop(), весь остальной код остаётся без изменений:

Листинг №2. Простейший калькулятор, сложение чисел применяя фильтрацию сигнала и обработку дребезга
void loop() 
{
  //Инструкции подавления дребезга контактов кнопки
  currentButtonState = getPressedButton();
  if(currentButtonState != previousButtonState)
  {
    delay(5);
    currentButtonState = getPressedButton();
    if(currentButtonState != previousButtonState)
    {
      ButtonEventProc(currentButtonState);
      previousButtonState = currentButtonState;
    }
  }
}

        Ну и в дополнение еще одна небольшая фича - подзвучка нажатий кнопок. Вместо обычных сухих щелкающих нажатий, событие будет озвучиваться тоновым писком от пъезопищалки !!! Добавляем в начало скетча строку:

//Пин к которому подключена пъезопищалка

#define BUZZER 4

        Далее, tone(pin, frequency, duration) - функция подачи тонового сигнала, имеет три параметра pin - пин подключения пъезопищалки, frequency - частота звучания ноты, duration - длительность звучания. Встраиваем её вызов в функцию обработчик наращивания текущего значения при нажатии кнопки:

void Calculation(int numButton)
{
  //Здесь будет происходить подзвучка нажатий кнопок
  tone(BUZZER, 2349, 100);
  
  if(numButton == 0)
  {
    Amount = 0;
    Serial.print("Amount = ");
    Serial.println(Amount);
  }
  else
  {
    Serial.print(Amount);
    Serial.print(" + ");
    Serial.print(numButton);
    Serial.print(" = ");
    Amount = Amount + numButton;
    Serial.println(Amount);
  }
}   

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



Расскажи о нас

Сообщение

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

Последние комментарии