Клавиатура 4×4: подключение к ESP32 и Arduino

Матричная клавиатура

Шестнадцать кнопок на восьми проводах: цифры, буквы, звёздочка и решётка. Для кодовых замков и меню.

Как работает

Кнопки стоят на пересечениях четырёх строк и четырёх столбцов. Контроллер по очереди опускает строку в LOW и читает столбцы, подтянутые к питанию: низкий уровень на столбце — нажата кнопка на этом пересечении.

Библиотека Keypad делает опрос, фильтр дребезга и выдаёт символ: char key = keypad.getKey();. Раскладку задаёт массив 4×4.

Выводы

ВыводНазначение
C1столбец 1
C2столбец 2
C3столбец 3
C4столбец 4
R1строка 1
R2строка 2
R3строка 3
R4строка 4

Подключение к ESP32

Клавиатура 4×4ESP32
C1GPIO26
C2GPIO25
C3GPIO33
C4GPIO32
R1GPIO13
R2GPIO12
R3GPIO14
R4GPIO27

Схема из примера «Матричная клавиатура 4x4».

Матричная клавиатура 4x4

Открыть пример целиком
Код скетча
const int ROWS[4] = {13, 12, 14, 27};
const int COLS[4] = {26, 25, 33, 32};
const char KEYS[4][4] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'},
};

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < 4; i++) {
    pinMode(ROWS[i], OUTPUT);
    digitalWrite(ROWS[i], HIGH);
    pinMode(COLS[i], INPUT_PULLUP);
  }
}

char scan() {
  for (int r = 0; r < 4; r++) {
    digitalWrite(ROWS[r], LOW);          // прижимаем одну строку
    for (int c = 0; c < 4; c++) {
      if (digitalRead(COLS[c]) == LOW) { // и смотрим, какой столбец ответил
        digitalWrite(ROWS[r], HIGH);
        return KEYS[r][c];
      }
    }
    digitalWrite(ROWS[r], HIGH);
  }
  return 0;
}

void loop() {
  char key = scan();
  if (key) {
    Serial.printf("нажато: %c\n", key);
    delay(200);
  }
}

Подключение к Arduino Uno

Клавиатура 4×4Arduino Uno
C1D6
C2D7
C3D8
C4D9
R1D2
R2D3
R3D4
R4D5

Схема из примера «Arduino Uno: клавиатура 4x4 без библиотеки».

Arduino Uno: клавиатура 4x4 без библиотеки

Открыть пример целиком
Код скетча
// Матричная клавиатура: шестнадцать кнопок на восьми выводах.
//
// Кнопки стоят на пересечениях четырёх строк и четырёх столбцов.
// Отдельного провода у кнопки нет — есть провод строки и провод
// столбца, и нажатие их соединяет.
//
// Отсюда способ опроса. Строки — выходы, и по очереди одна из них
// прижимается к земле. Столбцы — входы с подтяжкой, и тот из них, что
// стал LOW, пересекается с прижатой строкой ровно в одной точке. Это и
// есть нажатая кнопка.
//
// Восемь выводов вместо шестнадцати — ради этого всё и затевалось.

const int ROWS[4] = { 2, 3, 4, 5 };
const int COLS[4] = { 6, 7, 8, 9 };

const char KEYS[4][4] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' },
};

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 4; i++) {
    pinMode(ROWS[i], OUTPUT);
    digitalWrite(ROWS[i], HIGH);
    pinMode(COLS[i], INPUT_PULLUP);
  }
  Serial.println("нажимайте клавиши на схеме");
}

char scan() {
  for (int r = 0; r < 4; r++) {
    digitalWrite(ROWS[r], LOW);
    for (int c = 0; c < 4; c++) {
      if (digitalRead(COLS[c]) == LOW) {
        digitalWrite(ROWS[r], HIGH);
        return KEYS[r][c];
      }
    }
    digitalWrite(ROWS[r], HIGH);
  }
  return 0;
}

void loop() {
  char key = scan();
  if (key) {
    Serial.print("нажато: ");
    Serial.println(key);
    delay(200);
  }
}

В железе

На ESP32 выводы GPIO34–39 только вход и без внутренней подтяжки — для столбцов с INPUT_PULLUP они не годятся. Не используйте и GPIO6–11 (к ним подключена флеш-память).

Частые ошибки

Другие детали