Підключення тактових кнопок до Arduino

Кнопка це засіб взаємодії людини з програмою. За допомогою кнопок можна налаштовувати параметри пристою під час його роботи. Тактова кнопка відрізняється від звичайної тим що немає фіксації.

Схема підключення

button-scheme

Код програми

Даний приклад при натисканні на кнопку, почергово вмикає вимикає світлодіод. Також використовується програмний захист від брязкіту контактів.

Wiki

Брязкіт контактів (англ. contact bounce) — небажане замикання й розмикання контактів в момент комутації, що виникає в електричних і електронних перемикачах і яке не передбачене заданою дією пристрою (процес триває приблизно упродовж від декількох до десятків мілісекунд).

bounce
#include <Arduino.h>

#define BUTTON_PIN 2  // Пін тактової кнопки
#define LED_PIN 13    // Пін світлодіода



void setup()
{
  pinMode(BUTTON_PIN, INPUT);  // Пін кнопки встановлюєм як вхід
  pinMode(LED_PIN, OUTPUT);    // Пін світлодіода встановлюєм як вихід
}

void toggle_led()
{
  static bool pin_led_state = false;       // Змінна стану світлодіода
  pin_led_state = !pin_led_state;          // Змінюєм стан на протилежний
  digitalWrite(LED_PIN, pin_led_state);    // Записуєм стан в порт
}

void read_button()
{
  static bool flag_read_button = true;     // Прапорець читання кнопки
  static unsigned long timer = 0;           // Змінна часу останнього натискання
 
  if (flag_read_button)                    
  {
    if (digitalRead(BUTTON_PIN))        // Якщо кнопка натиснута
    {
      flag_read_button = false;         // Вимикаєм читання
      timer = millis();                 // Зберігаєм час натискання
    }
  }
  else                                  
  {
    if (digitalRead(BUTTON_PIN))        // Якщо кнопка утримується
    {
      timer = millis();                 // Перезаписуєм час натискання
    }
    else                                // Якщо кнопку відпустили  
    {
      if ((millis() - timer) > 50)     // Очікуєм 50 мілісекунд коли закінчиться брязкіт 
      {
        toggle_led();                  // Перемикаєм стан світлодіода на протилещний
        flag_read_button = true;       // Вмикаєм читання кнопки
      }
    }
  }
}

void loop()
{
  read_button();                       // Цикл читання кнопки
  // Виконуєм якусь роботу без блокування !(без delay())
}

Код програми для single, double, triple long press

Наступний приклад дозволяє зловити одиночне, подвійне, потрійне, 4, 5 . . . натискання та довге натискання. Програма виводить результат натискання в монітор серійного порта.

#include <Arduino.h>

#define BUTTON_PIN 2
#define LED_PIN 13

int click;                          // Змінна для зберігання кількості натискань
bool buttton_finished = false;      // Прапорець готовності підрахунку натискань

void setup()
{
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
}

void toggle_led()
{
  static bool pin_led_state = false;
  pin_led_state = !pin_led_state;
  digitalWrite(LED_PIN, pin_led_state);
}

void read_button()
{
  static bool flag_read_button = true;    
  static unsigned long timer = 0;
  static unsigned long timer_counter = 0;       // Змінна часу short press
  static unsigned long timer_long_press = 0;    // Змінна часу long press
  static int _click = 0;                       // Змінна для підрахунку натискань

  if (flag_read_button)
  {
    if (_click)                               // Якщо були натискання 
    {
      if ((millis() - timer_counter) > 400)   // Якщо пройшло більше 400 ms завершуєм підрахунок натискань
      {
        click = _click;                       // Зберігаємо кількість натискань у зовнішню змінну
        buttton_finished = true;              // Дозволяєм зчитувати зовнішню змінну
        _click = 0;                           // Обнуляєм внутрішню змінну натискань
      }
    }
    if (digitalRead(BUTTON_PIN))
    {
      flag_read_button = false;
      timer = millis();
      timer_long_press = timer;              // Зберігаєм час натискання для long press
    }
  }
  else
  {
    if (digitalRead(BUTTON_PIN))
    {
      timer = millis();
    }
    else
    {
      if ((millis() - timer) > 30)
      {
        if ((millis() - timer_long_press) > 1000)  // Якщо кнопка утримувалась більше 1 секунди long press
        {
          _click = 99;
        }
        else if ((millis() - timer_counter) > 400)   // Якщо від попереднього натискання пройшло більше 400 ms 
        {
           _click = 1; // одне натискання
        }
        else                                  
         {
           _click++;                    // Збільшуєм кількість натискань
         } 
         timer_counter = millis();      // Зберігаємо час останньго натискання
        flag_read_button = true;
      }
    }
  }
}

void action()
{
  if (buttton_finished)                 // Якщо підрахунок натискань закінчено 
  {
    buttton_finished = false;           // Зчитуєм кількість натискань та очікуєм наступної готовності
    if (click == 1)
    {
      Serial.println("single click");
      toggle_led();
    }
    else if (click == 2)
    {
      Serial.println("double click");
    }
    else if (click == 3)
    {
      Serial.println("triple click");
    }
    else if (click == 99)
    {
      Serial.println("long press");
    }
    else
    {
      Serial.println(click);
    }
  }
}

void loop()
{
  read_button();      // Цикл читання кнопки
  action();           // Цикл обробки результатів натискання кнопки
// Виконуєм якусь роботу без блокування !(без delay())
}

Підключення декількох кнопок на один вхід Arduiono

Щоб підключити декілька кнопок до одного входу Arduino, ми використаєм АЦП (Аеалого Цифровий Перетворювач). По принципу роботи це звичайеий резистивний подільник напруги. При натисканні на першу кнопка на вхід мікроконтролера приходить 5 вольт. При натисканні на другу R1 та R2 утворюють резистивний подільник напруги, на вхід приходить 2.5 вольта. Третя кнопка утворює подільник R2 + R3 верхне плече та R1 нижнє плече, на вхід отримуєм 1.6 вольта. Четверта R2 + R3 + R4 та R1, на вході буде 1.2 вольта.

Калькулятор резистивного подільника напруги

Схема підключення

buttoms-sheme

Код порограми

#include <Arduino.h>
#define BUTTON_PIN A0

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

void loop()
{
  int button = analogRead(BUTTON_PIN);
  if (button > 950)
  {
    Serial.println("1");
  }
  else if (button > 450)
  {
    Serial.println("2");
  }
  else if (button > 300)
  {
    Serial.println("3");
  }
  else if (button > 200)
  {
    Serial.println("4");
  }
  delay(100);
}

Наступний приклад з захистом від брязкіту контактів

#include <Arduino.h>
#define BUTTON_PIN A0

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

void read_button()
{
  static unsigned long timer = 0;
  static bool flag_read_button = true;
  static int read_val = 0;

  if (flag_read_button)
  {
    read_val = analogRead(BUTTON_PIN);
    if (read_val > 10)
    {
      flag_read_button = false;
      timer = millis();
    }
  }
  else
  {
    if (analogRead(BUTTON_PIN) > 10)
    {
      timer = millis();
    }
    else
    {
      if ((millis() - timer) > 50)
      {
        flag_read_button = true;
        if (read_val > 950)
        {
          Serial.println("button 1");
        }
        else if (read_val > 450)
        {
          Serial.println("button 2");
        }
        else if (read_val > 300)
        {
          Serial.println("button 3");
        }
        else if (read_val > 200)
        {
          Serial.println("button 4");
        }
      }
    }
  }
}

void loop()
{
  read_button();
}

Замість виводу значення кнопок в термінал підсталяєм свої дії.

коментарі 2

  1. The next time I read a blog, I hope that it doesnt disappoint me as much as this particular one. I mean, I know it was my choice to read through, nonetheless I actually believed you would probably have something interesting to say. All I hear is a bunch of complaining about something that you could possibly fix if you were not too busy seeking attention.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *