Amateur Radio Station R9AL

      Сегодня мы познакомимся с матричной клавиатурой. Обычно, для того чтобы подключить кнопку к Ардуино, мы брали кнопку и просто подключали её на свободный пин. Но что если кнопок больше чем свободных выводов? Можно ли подключить большее число кнопок, используя меньшее число выводов? Оказывается можно, если кнопок больше 5-ти, то можно соединить их в матрицу и тогда количество кнопок, которое мы можем подключить будет, зависеть от того, сколько колонок и строк в нашей матрице. При использовании матричного соединения кнопок, с помощью пяти проводов можно подключить 6 кнопок, при использовании 6 проводов - уже 9 кнопок, при использовании 7 проводов - 12 кнопок. Далее количество кнопок, которое мы можем подключить, растет в геометрической прогрессии. Например, для подключения 16 кнопок, необходимо всего 8 проводов, тогда как при обычном подключении в два раза больше:



Например, такая пленочная матричная клавиатура есть и в среде Tinkercad:



Соберем простую схему и разберемся, как же работает такая клавиатура:



Выводы Arduino D2-D5 запрограммированы на выход и подключены к клавиатуре через разделительные диоды, которые нужны для того, чтобы не вывести из строя ардуино, нажав одновременно две клавиши. Выводы Arduino D6-D9 запрограммированы как входы, и чтобы избежать помех, подтянуты к плюсовой шине питания через резисторы R1-R4.

Принцип работы такой клавиатуры очень простой, с контроллера на выводы 1,2,3,4 клавиатуры на каждый вывод по очереди подается сигнал низкого уровня. Если ни одна кнопка не нажата, то на всех выводах A,B,C,D высокий уровень. Но стоит только нажать кнопку - низкий уровень через нее и через соответствующий диод шунтирует соответствующий вывод. Например, если нажать кнопку S2, то как только на выводе 1 клавиатуры появится сигнал низкого уровня - низкий уровень появится также и на выводе B клавиатуры. Таким образом любую нажатую кнопку очень просто вычислить, зная на каких выводах клавиатуры низкие уровни.

Соберем эту схему в среде Tinkercad:



И напишем простую программу:

int i = 2;            // переменная i будет перебирать выходы
int j = 6;            // переменная j будет перебирать входы

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  Serial.begin(9600); //данные о нажатой кнопке будем выводить в монитор порта
}

void loop()
{

  for (int i=2; i < 6; i++)   // цикл for будет выполняться пока i < 5
  {                          
      digitalWrite(i, 0);     // на выходе i устанавливаем низкий уровень
      for (int j=6; j < 10; j++)  // цикл for будет выполняться пока j < 10
      {
    	if(digitalRead(j)==0)     // перебираем поочередно входы и если обнаруживаем низкий уровень, 
  	 {                        // то выполняем условия в фигурных скобках
          if(i==2 && j==6) Serial.println("D"); // если низкий уровень на D2 и D6, то нажата кнопка D
          if(i==2 && j==7) Serial.println("C"); // если низкий уровень на D2 и D7, то нажата кнопка C
          if(i==2 && j==8) Serial.println("B"); // если низкий уровень на D2 и D8, то нажата кнопка B
          if(i==2 && j==9) Serial.println("A"); // если низкий уровень на D2 и D9, то нажата кнопка A
          if(i==3 && j==6) Serial.println("#"); // если низкий уровень на D3 и D6, то нажата кнопка #
          if(i==3 && j==7) Serial.println("9"); // если низкий уровень на D3 и D7, то нажата кнопка 9
          if(i==3 && j==8) Serial.println("6"); // если низкий уровень на D3 и D8, то нажата кнопка 6
          if(i==3 && j==9) Serial.println("3"); // если низкий уровень на D3 и D9, то нажата кнопка 3
          if(i==4 && j==6) Serial.println("0"); // если низкий уровень на D4 и D6, то нажата кнопка 0
          if(i==4 && j==7) Serial.println("8"); // если низкий уровень на D4 и D7, то нажата кнопка 8
          if(i==4 && j==8) Serial.println("5"); // если низкий уровень на D4 и D8, то нажата кнопка 5
          if(i==4 && j==9) Serial.println("2"); // если низкий уровень на D4 и D9, то нажата кнопка 2
          if(i==5 && j==6) Serial.println("*"); // если низкий уровень на D5 и D6, то нажата кнопка *
          if(i==5 && j==7) Serial.println("7"); // если низкий уровень на D5 и D7, то нажата кнопка 7
          if(i==5 && j==8) Serial.println("4"); // если низкий уровень на D5 и D8, то нажата кнопка 4
          if(i==5 && j==9) Serial.println("1"); // если низкий уровень на D5 и D9, то нажата кнопка 1
          delay(1000);
         }
      } 
      digitalWrite(i, 1);  //возвращаем выход i в высокоуровневое состояние
  }
}


Программа очень простая, работает без применения библиотек, а как она работает понятно из комментариев. Конечно неплохо было бы в нее добавить еще и подавление дребезга контактов, но для демонстрации работы матричной клавиатуры этого кода достаточно. Можно написать программу с использованием стандартной библиотеки Keypad.h (она по умолчанию установлена и в Tinkercad и в Arduino IDI) :
#include < Keypad.h>

const byte ROWS = 4; // четыре строки в матричной клавиатуре
const byte COLS = 4; // четыре колонки в матричной клавиатуре
char hexaKeys[ROWS][COLS] = {  // определяем названия кнопок на клавиатуре
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // подключаем строки к соответвующим пинам контроллера
byte colPins[COLS] = {5, 4, 3, 2}; // подключаем колонки к соответвующим пинам контроллера


//инициализируем клавиатуру
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

void setup(){
  Serial.begin(9600);
}
  
void loop(){
  char customKey = customKeypad.getKey();
  
  if (customKey){
    Serial.println(customKey);
  }
}
Разбирать как работает библиотека мы не будем, но за счет баблиотеки программа получилась еще проще, фактически после инициализации программы мы просто постоянно обращаемся к ней и если нажата какая-то кнопка, то выводим название кнопки в монитор порта.





Copyright © R9AL 2021 Все права защищены

Рейтинг@Mail.ru Яндекс цитирования