Ардуино и клавиатуры (полный гайд)

Привет, жители Хабра! Сегодня я решил сделать полный гайд по клавиатурам для Arduino.
Внимание! Статья ориентирована преимущественно на новичков!

Во многих проектах появляется необходимость создания возможности ввода данных пользователем. Если вам нужно реализовать большое количество кнопок(относительно), то подключать их по-отдельности становится и долго, и нерационально. Для этой цели лучше выбрать какую-нибудь клавиатуру, но как и к любому выбору, к нему нужно подходить осознано. Какие же бывают виды клавиатур и как с ними взаимодействовать?

Глобально, все модули данного типа можно поделить на две большие категории: матричные и аналоговые.

Матричные клавиатуры


Самый простой, дешёвый и популярный вид клавиатур. Он относительно прост в изготовлении и заполняет собой большую часть рынка модулей ардуино. Выглядит чаще всего следующим образом:

image

image

Принцип работы


Понять как устроена данная клавиатура можно изучив следующую схему:

image

Чтобы понять какая кнопка была нажата, нужно подавать сигнал на первые четыре контакта модуля и смотреть какой сигнал возвращается со второй. Но не стоит пугаться того, что вам придется писать алгоритмы обработки для восьми пинов вручную — в этом нам поможет готовая библиотека «keypad.h», благодаря которой нам не придется изобретать велосипед.

Подключение к плате


Подключение собственно модуля


В этой статье я воспользуюсь следующей схемой подключения:

image

У Вас наверное возникает вопрос: «Почему я решил использовать пины со второго по девятый, пропустив нулевой и первый?» — дело в том, что некоторые модули, используют их в качестве каналов RX и TX для получения и передачи данных соответственно. К примеру, блютуз модуль. Поэтому с учётом возможного дополнения проекта другими модулями, было решено оставить данные пины подключения свободными.

Написание скетча


Для начала, для того, чтобы получить возможность использовать библиотеку для подключения клавиатур в коде, нужно установить её на ваше устройство. Это можно сделать следующим образом: в самой Arduino IDE нажимаем Скетч -> Подключить библиотеку -> Управлять библиотеками… либо используем комбинацию горячих клавиш «Ctrl + Shift + I». В поиске вбиваем «keypad.h»(без скобочек) и нажимаем «Установка».

После установки приступаем к написанию скетча:

#include <Keypad.h> // подключаем библиотеку для управление клавиатурой

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

byte rowPins[ROWS] = {5, 4, 3, 2}; //к каким выводам подключаем управление строками
byte colPins[COLS] = {9, 8, 7, 6}; //к каким выводам подключаем управление столбцами

//передаем все эти данные библиотеке:
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);//выводим нажатый символ в монитор порта
}

}

Плюсы и минусы


Минусы


  • Слишком много пинов нужно подключить для работы. Это довольна крупная проблема, если вы создаёте не калькулятор или кодовый замок, а более масштабный проект, в котором еще нужно задействовать огромное количество различных модулей — возможно им просто не хватит пинов.
  • Слишком низкое качество выполнения модуля: никто вам не гарантирует постоянный стабильный сигнал. Оригинальные клавитуры выполнены не на очень высоком уровне, а если вы вообще сделали заказ на Aliexpress, то скорее всего, вам предстоит исправлять косяки китайских инженеров паяльником, чтобы добится стабильной работы.
  • Используется дополнительная библиотека, которая также будет занимать память микроконтроллера, которой у него и так не очень много. Если вы пишите большой проект с множеством функций и вычислений и вам каждый байт на счету нужно считывать данные с клавиатуры вручную либо использовать аналоговую клавиатуру.

Плюсы


  • Низкая цена
  • Легко найти в продаже

Аналоговые клавиатуры


Принцип работы


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

image

Подключение к плате


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

Итак: аналоговый выход клавиатуры соединяем с любым аналоговым пином на плате, контакт VCC на плате соединяем с 3.3V(не смотрите на надпись на самой клавиатуре, которая гласит о 5V — это ошибка), а GND на плате с GND на модуле. Вы можете воспользоватся следующей схемой:



Написания скетча


Здесь не нужно использовать сторонние библиотеки, т.к. всё предельно просто и понятно. Вот собственно и сам код, который считывает нажатую кнопку и выводит её номер, от 1 до 16(слева на право, с верху в низ) либо 0 если ничего не нажато, в монитор порта.

unsigned const short int KEYPAD_PIN = 0;//аналоговый порт для клавиатуры

void setup() {
  Serial.begin(9600);
  analogReadResolution(10);//все аналоговые значение будут в диапазоне 0...1023
}

void loop() {
  Serial.println(getPressedKeypadButton());//выводим номер нажатой кнопки в монитор порта
}

short int getPressedKeypadButton(){//считывает нажатия keypad`a
//возвращает значение от 1 до 16 в зависимости нажатой кнопки или 0 если ничего не нажато
  const int OCCURACY = 5;//ошибка в точности определения значений
  int sensorValue = analogRead(KEYPAD_PIN);//читаем значение с датчика
  int keys[] = {1016, 937, 860, 794, 683, 641, 604, 571, 509, 485, 464, 444, 407, 328, 275, 236};//массив примерных значений для клавиш(0-15, где 0=1, 1=2 и т.д.)
  if(sensorValue > -OCCURACY && sensorValue < OCCURACY){return 0;}//если ничего не нажато, то сразу возвращаем 0
  for(short int i = 0; i < 16; i++){//проверяем в цыкле с каким по номеру элементом массива совпадает значение с датчика
    if(sensorValue > (keys[i] - OCCURACY) && sensorValue < (keys[i] + OCCURACY)){
      return i+1;//возвращаем на один больше, т.к. при проверке у нас 0 считается первой кнопкой, но для удобства 0 будет отсутсвием сигнала
    }
  }
}

Плюсы и минусы


Плюсы


  • Очень простое подключение
  • Занимает лишь один пин
  • Экономит память, которую вы не тратите под библиотеку
  • Обеспечивает стабильную работу(при условии, если вы не будете нажимать более одной кнопки одновременно)

Минусы


  • Стоит дороже матричных клавиатур
  • Скорее всего единственным способом покупки будет заказывать с Китая и доставка займёт какое-то время

Итоги


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

На этом у меня всё. Оставляйте свои вопросы в комментариях, пишите своё мнение и встретимся на просторах Хабра!

Комментарии 32

    0
    пропустив нулевой и первый
    — их лучше всегда пропускать, так как по ним происходит заливка скетча.
      0
      И это верно, но так-как статья рассчитана на новичком, то решил уточнить этот момент.
      –3
      я просто оставлю это здесь:

      habr.com/ru/info/help/posts
      Признаки хороших и плохих публикаций
      Плохая публикация:
      содержит реферальные ссылки на что угодно;
        0

        А тут есть рефы?

          0
          Согласен, где здесь реферальные ссылки? Единственная ссылка, которая есть в статье, это ссылка на одну из клавиатур с алика, потому-что я рассказывал о подключении и использовании аналоговых клавиатур на её примере, а сам код может быть переделан под любую из них. И это ни в коем случае не реклама, по-этому я оставил универсальные советы о подключении, которые можно использовать при работе с любым модулем данного типа.
            –1
            использование этой китайской
            вот реферальная ссылка (используемая в статье)
            www.aliexpress.com/item/32635207928.html?spm=a2g0s.9042311.0.0.2c0a4c4dKghr6P

            вот НЕ реферальная ссылка
            www.aliexpress.com/item/32635207928.html

            ещё вопросы?
              +2
              Извиняюсь — мой косяк. Копипастнул просто адрес страницы, на которой был, не обратив внимания. Уже в статье исправил, не бросайте помидорами, пожалуйста.
                +2

                spm это не реф. Это обычный родной трекерный параметр али. Если-б ссылка была аля али.паб то да, а это трекинг. Тоже вещь неприятная (для носителей шапочек из фольги), но автору никаких бонусов не даст.
                И в том и в том случае — вы могли-бы написать автору в ЛС про этот косяк, явно ссылка приведена не для получения миллионов рублей на продаже клавиатур для дуины.

                  +1

                  Лучше такое человеку в личку написать…

            0
            Мне кажется статьи про ардуино надо убрать с хабра — они разжижают мозг.
              0
              Боюсь, проблема не в ардуино. Статей «ни о чём» — на любую тему хватает.
              +6
              Аналоговая клава — это адский мусор, любая наводка приводит к ложным срабатываниям. Ладно бы еще 4 кнопки на вход, тут дельта между значениями была бы вменяемой. Но 16 это перебор.
              Еще в скетче нет обработки bounce на кнопках. Надо считывать несколько значений и усреднять, иначе количество ложных срабатываний просто зашкалит.
                –5
                Возможно вы имели дело с браковаными либо некачественными модулями. Я, лично, использую аналоговую клавиатуру для своего проекта и не фиксирую ложных нажатий вообще. Возможно просто я использую модель в которой физически устранены ложные срабатывания, ведь кнопки очень жесткие и громкие при нажатиях и буквально чувствуется, как сильно кнопка уходит вниз при нажатии. Конечно эти выводы я делаю не разбирая клавиатуры, ведь не вижу смысла исправлять то, что стабильно работает.
                –1
                С клавиатурами для ардуино есть одна маленькая проблема: если вдруг захочется больше чем шестнадцать кнопок, то все становится трагично. Что только ни приделывают в качестве той же qwerty-клавиатуры, включая аж ее саму целиком через переходник.
                  +1
                  Не вижу проблемы. Если нужно больше 16 кнопок, можно последовать одному из следующих пунктов:
                  • Подключить несколько аналоговых клавиатур в разные аналоговые порты
                  • Подключать кнопки по-отдельности в разные цифровые пины
                  • Реализовать собственный модуль, который будет использовать к примеру 3-4 пина и работать по следующему принципу: нажата 1-4 кнопка — сигнал на соотвествующий пин, нажата шестая — на два первых пина, седьмая — на второй и третий, с 8-ой аналогично и так комбинируя сигналы с разных пинов, можно получать информацию о нажатой кнопки, ну а если вам нужно слишком много кнопок, можно выделить собственный микро-контроллер для клавиатуры, используя все его пины для обработки нажатий, а второму микроконтроллеру передавать уже только уже готовую информацию о нажатой кнопке.
                    –2
                    Да и ps/2 тот же приделывается. Но это совсем не тот «подключи и играй», которого хочется от ардуины. Вот захотел сорок кнопок — и вот вместо «тыц готовый модуль» жонглируешь пинами, резисторными делителями, триггерами и бог невесть чем.

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

                      Приделывал PS/2 к ардуине, кроме разъёма ничего и не понадобилось.
                      А вообще для экономии пинов набор из входных + выходных сдвиговых регистров поможет практически сколько влезет кнопок сделать :-)

                        0
                        Даже регистров уже не надо, есть специализированные микросхемы расширителя I/O. Например, MCP23017 — подключается к SPI или i2c, даёт 16 двунаправленных линий ввода-вывода. Их можно подключить восемь штук сразу — и хоть по индивидуальному проводу к каждой кнопке полноразмерной клавиатуры от PC делай.
                  +2
                  В схеме подключения матричной клавиатуры должны быть защитные диоды и подтягивающие резисторы. Схема и объяснения.
                    +1
                    Если коммутировать линии (на схеме по Вашей ссылке — столбцы) выходами с открытым стоком, то диоды не нужны. Правда, на atmega нет нормального режима вывода как выхода с открытым стоком, поэтому придется извращаться переключая режим вывода. Подтягивающие резисторы для входов можно использовать внутренние.
                      0
                      В форумах описывают случаи выхода из строя портов МК при нажатии двух кнопок одновременно.
                        0
                        Если опрос столбцов проводить выводами, работающими в режиме пуш-пулл, то при одновременном нажатии двух кнопок, подключенных к разным столбцам и одной и той же строке произойдет замыкание двух выходов, имеющих разный логический уровень. Естественно, ни к чему хорошему это не приведет — даже если выходные ключи контроллера и не выгорят, то сбои точно гарантированы. Если же Вы будете проводить опрос столбцов выходами с открытым стоком, которые могут тянуть линию только «вниз», то никакого замыкания не будет. Собственно диоды в Вашей схеме и делают пуш-пулл выходы неким сурогатным аналогом выходов с открытым стоком, правда, ценой поднятия уровня логического нуля на величину падения не диодах, что не совсем хорошо сточки зрения помехозащищенности.
                        К сожалению, насколько помню, выходные каскады atmega, применяемых в Ардуинах, не имеют штатного режима работы в режиме с открытым стоком. Но это можно сэмулировать, переключая режим ножки между выходом с логическим 0 (эквивалентно установке выхода с открытым стоком во включенное состояние выходного транзистора) и входом с отключенной подтяжкой (эквивалентно установке выхода с открытым стоком в выключенное состояние выходного транзистора). Естественно, проводить эти манипуляции стоит прямым обращением к регистрам, а не ардуиновскими функциями конфигурирования выводов, занимающими десятки (если не сотни) тактов процессора.
                          0
                          Здесь очень много «если», причем программной реализации. Отладка программ новичками (да и не только) может привести к неосознанным действиям с режимами портов. Аппаратная защита исключает этот фактор. В любом случае я не стал бы соединять напрямую порты ввода/вывода.
                            0
                            Здесь очень много «если», причем программной реализации. Отладка программ новичками (да и не только) может привести к неосознанным действиям с режимами портов.
                            Этим эмбеддинг кардинально и отличается от обычного программирования, что ошибки в программе могут приводить к повреждению оборудования. И если с условным опросом клавиатуры этого еще можно избежать, то, например, при управлении силовыми ключами в двухтактном включении и т.д. «бах» можно устроить вполне реальный.
                            Возвращаясь к нашей клавиатуре — просто на этапе отладки, пока не убедились, что все работает правильно, не надо нажимать по две клавиши сразу. А как только все заработало как надо — тогда на здоровье, жмите хоть все сразу.
                            Впрочем, Ваше мнение может быть и более полезно, чем мое для типового Ардуинщика, не желающего вникать в детали и становиться профессионалом.
                              0
                              Тут даже дело не в том, что нет желания вникать в детали. Любая электроника должна быть защищена. Вы же не будете писать в даташите на устройство «две кнопки сразу не нажимать, процедуру опроса клавиатуры не менять».
                                0
                                Немного не понял, что Вы здесь имеете ввиду под даташитом. Если инструкцию конечного пользователя готового устройства, то почему нельзя нажимать сразу несколько клавиш? В устройстве с отлаженной программой вполне можно нажимать сколько угодно клавиш одновременно. А какие есть ограничения в процессе отладки — это конечного пользователя никак не касается.
                                процедуру опроса клавиатуры не менять
                                — ну если кому-то приспичило перепрограммировать устройство — то это его личное дело, но и ответственность за свои действия несет только он.
                                  0
                                  Речь идет о монтажной схеме в статье, для которой предложена схема аппаратной защиты. Для меня важнее было обратить внимание на этот нюанс. Спасибо, что поддержали диалог. Ваше решение имеет право реализации.
                    +1
                    Есть ещё очень удобная микросхема MM74C922 16-Key Encoder.
                    Защита от дребезга, встроенные диоды и прочие «плюшки».
                    PDF c datasheet гуглится легко.

                      +1
                      Да уж, статьи на хабре о подключении матричных клавиатур к Ардуино. :(
                      Только у меня складывается впечатление, что «знание» Ардуино безвозвратно портит людей?
                      А не думали ли Вы, что гораздо и проще и правильнее подключить PS/2 Numpad, коих более чем много на упомянутом али? И выводов займет мало и не будет сюрпризов с кнопками через некоторое время (как это бывает в аналоговых клавиатурах мониторов)?
                      Но да, для этого надо бросить Ардуину в дальний ящик и заняться программированием.
                        +2

                        Вы слишком категоричны. Увлечение ардуиной для утилитарных задач дает очень хороший старт для энтузиастов без знаний. Для многих это остается увлечением ради одной задачи, например поливалки для теплиц у моего брата — он ее спаял и никогда больше не прикасался к дуине и МК вообще. И тут играет важную роль а) низкий порог входа, потому что на ардуине я за вечер смог сделать свой GPS — SD логгер ВООБЩЕ без знаний в Си/асм или алгоритмах и б) большое комьюнити в интернете. Со своей колокольни вы можете смотреть на это как на детей играющих паровозиком в песочнице, однако если оно выполняет своюи задачи за минимальные затраты времени и денежных вложений — оно займет обширную нишу.


                        А про PS/2 numpad — смешно. Готовое изделие, которое нужно будет разбирать в 99% для своих поделок и полуфабрикат...

                          +1
                          От того и грустно, что Habr становится пристанищем для статей «про детей и паровозики в песочнице». :(

                          P.S. Зачем разбирать Numpad? У него же вполне простой и понятный интерфейс PS/2, по которому документации ну очень много.
                            +1

                            Это не грустно, это нормально. На одних гиках жизни нет, их мало, зато в таких "масло-масленых" статьях есть люди уже прошедшие весь этот путь и могущих ткнуть лицом в типичные ошибки новичков и вовремя остановить их от неверного пути. Мне-бы такое в те года когда я начинал — может сейчас-бы уже знал STM или PIC, а не рукоблудил с дуинами pro mini, однако тогда на хабре были статьи от которых челюсть падала на стол от непонимания всего этого "дзюдо".


                            Разбирать нампад надо т.к. чаще всего человеку нужна не внешняя клавиатура, а клавиши встроенные куда-то. У меня вот клавиатура в ракете, клавиатура в макете устройства из Counter-Strike, клавиатура в ящике кодовом, клавиатура в ящике координатном, клавиатура в рации… Для всех этих вещей мне пришлось-бы разбирать нампад, а это лишние действия.

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

                      Самое читаемое