Использование клавиатуры совместно с Arduino. Добавление метода ввода к Arduino

На iOS - iPhone, iPod touch 10.07.2019
На iOS - iPhone, iPod touch

Клавиатуры позволяют пользователям вводить данные во время выполнения программы. Данная статья показывает вам, как подключить к Arduino 12-кнопочную клавиатуру, и как использовать библиотеку Keypad.h.

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

В данной статье мы покажем, как использовать 12-кнопочную цифровую клавиатуру, похожую на ту, что вы можете увидеть на телефоне. 12-кнопочная клавиатура имеет три столбца и четыре строки. Нажатие кнопки замыкает вывод одной из строк с выводом одного из столбцов. Из этой информации Arduino может определить, какая кнопка была нажата. Например, когда нажата кнопка 1, замкнуты столбец 1 и строка 1. Arduino определит это и введет в программу 1.

На рисунке ниже показано, как внутри клавиатуры расположены строки и столбцы.

Эксперимент

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

Необходимые комплектующие

  • перемычки (необязательно);
  • макетная плата (необязательно).

Схема соединений

Подключите клавиатуру к плате Arduino, как показано на рисунке ниже.

Код

/* Пример кода для руководства по работе с матричной клавиатурой 3x4 совместно с платой Arduino. Данный код выводит значение нажатой на клавиатуре кнопки в монитор последовательного порта. */ #include "Keypad.h" const byte Rows= 4; // количество строк на клавиатуре, 4 const byte Cols= 3; // количество столбцов на клавиатуре, 3 // определяем массив символов соответствующий распределению кнопок на клавиатуре: char keymap= { {"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}, {"*", "0", "#"} }; // соединения клавиатуры с выводами Arduino задаются так: byte rPins= {A6,A5,A4,A3}; // строки с 0 по 3 byte cPins= {A2,A1,A0}; // столбцы с 0 по 2 // команда для библиотеки клавиатуры // инициализирует экземпляр класса Keypad Keypad kpd= Keypad(makeKeymap(keymap), rPins, cPins, Rows, Cols); void setup() { Serial.begin(9600); // инициализация монитора последовательного порта } // Если кнопка нажата, эта кнопка сохраняется в переменной keypressed. // Если keypressed не равна NO_KEY, то выводим значение в последовательный порт. void loop() { char keypressed = kpd.getKey(); if (keypressed != NO_KEY) { Serial.println(keypressed); } }

Заключение

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

Arduino и матричная клавиатура

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



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


Мембранные клавиатуры являются экономичным решением для многих приложений. Они довольно тонкие и могут легко монтироваться там, где они нужны. Клавиатура с 12 кнопками имеет три столбца и четыре ряда. При нажатии этой кнопки один из выходов строки будет выведен на один из выходов столбца. Из этой информации Arduino может определить, какая кнопка была нажата. Например, при нажатии клавиши 1 столбец 1 и строка 1 замыкаются. Arduino обнаружит это, и в программе будет индицирована цифра 1. Порядок расположения строк и столбцов внутри клавиатуры показан на рисунке ниже.



В данном случае воспользуемся платой Arduino Mega 2560, подключим к ее выводам с 1 по 7 линии матричной клавиатуры 3x4 и будем выводить получаемые с нее данные в последовательный порт. Схема подключения платы Arduino Mega 2560 и матричной клавиатуры показана ниже.



Код (скетч) взаимодействия Arduino и матричной клавиатуры представлен далее.


#include "Keypad.h" const byte Rows= 4; // число строк 4 const byte Cols= 3; // число столбцов 3 // расположение цифр и символов в матрице: char keymap= { {"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}, {"*", "0", "#"} }; // подключение к линиям Arduino: byte rPins= {A6,A5,A4,A3}; // строки с 0 по 3 byte cPins= {A2,A1,A0}; // столбцы с 0 по 2 // инициализация класса Keypad Keypad kpd= Keypad(makeKeymap(keymap), rPins, cPins, Rows, Cols); void setup() { Serial.begin(9600); // включаем последовательный монитор } // если клавиша нажата, ее номер сохраняется в переменной keypressed // если номер клавиши не равен NO_KEY, тогда он выводится в последовательный монитор void loop() { char keypressed = kpd.getKey(); if (keypressed != NO_KEY) { Serial.println(keypressed); } }

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

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

Большая часть текста содержит объяснение программного кода, его можно скачать либо посмотреть видео под статьей.

Сделать такую клавиатуру можно и самому. Для этого понадобится печатная плата, 12 или 16 обычных кнопок и соединительные провода. Я же буду использовать готовую.

Для чего нужна матричная клавиатура?

Для примера возьмем обычную кнопку. Как вы знаете, это простейшее электромеханическое устройство. Чтобы подключить ее к плате, нужно использовать стягивающий резистор, а также задействовать по одному контакту питания и «земли». Нажатием такой кнопки можно выполнить определенное действие, например можно управлять светодиодом, различными приводами, механизмами и так далее. А что, если нам необходимо подключить несколько кнопок? Тогда придется задействовать больше контактов и большее число проводов, да и без макетной платы уже не обойтись, плюс еще резисторы придется использовать в большем количестве.

Для этого и придумали такую клавиатуру, чтобы упростить подключение большего числа кнопок. Такие устройства встречаются везде — в клавиатурах компьютеров, калькуляторах и так далее.

Подключать ее к плате следует 8 выводами, каждый из них считывает значения с определенных строк и столбцов. Подключать их следует к выводам на панели Digital. Я подключу, например, к выводам от 2 до 9 включительно. Нулевой и первый трогать не желательно, поскольку они предназначены для UART интерфейса (например, для подключения блютуз-модуля). Рациональнее оставить их свободными.

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

После того, как вы установили в библиотеку, можно зайти в Ардуино IDE (программа с сайта Arduino) и посмотреть примеры скетчей.

Возьмем самый простой скетч для ознакомления. Он позволяет считывать значение с клавиатуры при нажатии определенной клавиши и выводить их в порт. В данном случае это монитор порта на компьютере.

#include // подключаем нашу библиотеку




{"2","5","8","0"},
{"3","6","9","#"},
{"A","B","C","D"}
};




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

if (customKey){
Serial.println(customKey);
}
}

Скетч очень простой. Стоит отметить первые строчки кода. Сначала подключаем библиотеку, затем указываем сколько строк и столбцов у клавиатуры, а потом нужно правильно расположить названия клавиш, чтобы было удобнее работать.

Если это сделать неправильно, то, например, при нажатии цифры 4, в порт выйдет цифра 6 или любой другой символ. Это можно определить опытным путем и расположить символы, как они расположены на клавиатуре.

В функции void setup указываем скорость последовательного соединения с монитором порта 9600 бод . Функция нужна только для подачи питания на модули. В функции Void Loop прописываем условие. Переменная Char используется для хранения только одного символа, например, 1, А или 5, что подходит к ситуации. Если нажатие зафиксировано, то происходит вывод символа в монитор порта с помощью функции Serial Print. В скобках нужно указывать, какую переменную выводим в порт. Если все сделано верно, в мониторе порта получим символ, на который нажимали. Не забудьте в мониторе порта внизу справа указать скорость передачи данных такую же, как в скетче.

Схема с дисплеем и матричной клавиатурой

Давайте выведем данные на дисплей.

Я использую дисплей, сопряженный с модулем I2C, который упрощает подключение. Для работы с дисплеем с шиной I2C необходимо установить еще одну библиотеку. Скачать ее можно .

Далее нужно указать размерность дисплея. Используемый в примере дисплей вмещает по 16 символов в каждой из 2-ух строк, это я и указываю. В функции Void Setup нужно подать питание на дисплей и включить подсветку. Делается это с помощью двух функций: lcd.begin и lcd.backlight .

#include // подключаем нашу библиотеку
#include
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte ROWS = 4; //число строк у нашей клавиатуры
const byte COLS = 4; //число столбцов у нашей клавиатуры
char hexaKeys = {
{"S","4","7","*"}, // здесь мы располагаем названия наших клавиш, как на клавиатуре,для удобства пользования
{"O","5","8","0"},
{"S","6","9","#"},
{"I","B","C","D"}
};
byte rowPins = {5, 4, 3, 2}; //к каким выводам подключаем управление строками
byte colPins = {9, 8, 7, 6}; //к каким выводам подключаем управление столбцами
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup(){
Serial.begin(9600);
lcd.begin(); // Инициализируем экран
lcd.backlight();
}
void loop(){
char customKey = customKeypad.getKey();
if (customKey){
Serial.println(customKey);
lcd.setCursor(1,4); //устанавливаем курсор
lcd.print(customKey);
}
}

В функции Voil Loop нужно в самом условии прописать строчку lcd.print для вывода данных на дисплей. И еще нужно предварительно установить положение курсора. В скобках идут 2 цифры: первая — это номер символа, а вторая — номер строки. Нужно помнить, что у этого дисплея отсчет строк и столбцов начинается не с единицы, а с нуля. То есть здесь имеются строчки под номерами 0 и 1, а не 1 и 2, как может показаться сначала. Затем загрузим код в плату и посмотрим, что будет.

Так как дисплей работает по интерфейсу I2C, подключаем к аналоговым выводам. Выходы SDA и SCL соответственно подключаем к А4 и А5, а остальные два — это уже питание и «земля».

Как видим, нажимая на любой символ, видим его отображение на дисплее.

Чтобы стереть строчку, вспомним калькулятор. Когда нужно было удалить значение, мы нажимали на кнопку сброса. Нажмем на такую кнопку в плате и можем заново набирать символы.

Подключение клавиатуры к Arduino и управляющее действие

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

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

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

Я буду использовать макетную плату и резистор (желательно использовать от 150 до 220 Ом). Двумя перемычками замкну схему, подключив их к пинам питания и земли на плате Ардуино.

Схема будет работать так: при нажатии на 1 включается светодиод, при нажатии на 2 — выключается.

Светодиод в примере подключен к пину 8 на плате Ардуино.

#include
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns
char keys = { // Define the Keymap
{"1","4","7","*"}, // здесь мы располагаем названия наших клавиш, как на клавиатуре,для удобства пользования
{"2","5","8","0"},
{"3","6","9","#"},
{"A","B","C","D"}
};
byte rowPins = { 5, 4, 3, 2 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins = { 9, 8, 7 ,6}; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);// Create the Keypad
#define ledpin 8
void setup()
{
pinMode(ledpin,OUTPUT);
Serial.begin(9600);
}
void loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case "1":
digitalWrite(ledpin, HIGH);
break;
case "2":
digitalWrite(ledpin, LOW);
break;
}
}
}

Давайте разберем скетч.

Возьмем первый скетч урока и просто его дополним. В начале с помощью полезной функции Define присвоим название подключенному к пину 8 светодиоду ledpin . В функции Void setup указываем сигнал со светодиода как выход.

Если бы не библиотека Кейпад для клавиатуры, пришлось бы прописывать то же самое для 8 пинов, с которыми связана клавиатура. В функции void loop условие. Нажатие определенной клавиши «приравнивается» к значению переменной key. Оператор Switch сравнивает значения переменной key и «дает» определенные команды в зависимости от этого значения. Состоит он из двух вспомогательных операторов Case и Break . Проще говоря, если будет найдено значение переменной, равное 1 , то будет выполняться действие. Оператор break служит командой выхода из оператора Case .

Соответственно при нажатии на 1 будет выполняться максимальная подача напряжения на светодиод и он будет гореть. При нажатии на 2 он гореть не будет. Это указывается в функции Digitat write , где в скобках задается название переменной и «указание» ей. Можно таким образом написать определенные команды для каждой кнопки и управлять большим количеством светодиодов или создать команду для включения всех светодиодов сразу.

Иногда мы сталкиваемся с проблемой нехватки портов на Arduino. Чаще всего это относится к моделям с небольшим количеством выводов. Для этого была придумана матричная клавиатура. Такая система работает в компьютерных клавиатурах, калькуляторах, телефонах и других устройств, в которых используется большое количество кнопок.

Для Arduino чаще всего используются такие клавиатуры:

Самыми распространенными являются 16 кнопочные клавиатуры 4x4. Принцип их работы достаточно прост, Arduino поочередно подает логическую единицу на каждый 4 столбцов, в этот момент 4 входа Arduino считывают значения, и только на один вход подается высокий уровень. Это довольно просто, если знать возможности управления портами вывода в Arduino , а так же портами входа/ввода.

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

Подключаем клавиатуру в любые порты ввода/вывода.

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

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

Int PinOut {5, 4, 3, 2}; // пины выходы int PinIn {9, 8, 7, 6}; // пины входа int val = 0; const char value { {"1", "4", "7", "*"}, {"2", "5", "8", "0" }, {"3", "6", "9", "#"}, {"A", "B", "C", "D"} }; // двойной массив, обозначающий кнопку int b = 0; // переменная, куда кладется число из массива(номер кнопки) void setup() { pinMode (2, OUTPUT); // инициализируем порты на выход (подают нули на столбцы) pinMode (3, OUTPUT); pinMode (4, OUTPUT); pinMode (5, OUTPUT); pinMode (6, INPUT); // инициализируем порты на вход с подтяжкой к плюсу (принимают нули на строках) digitalWrite(6, HIGH); pinMode (7, INPUT); digitalWrite(7, HIGH); pinMode (8, INPUT); digitalWrite(8, HIGH); pinMode (9, INPUT); digitalWrite(9, HIGH); Serial.begin(9600); // открываем Serial порт } void matrix () // создаем функцию для чтения кнопок { for (int i = 1; i <= 4; i++) // цикл, передающий 0 по всем столбцам { digitalWrite(PinOut, LOW); // если i меньше 4 , то отправляем 0 на ножку for (int j = 1; j <= 4; j++) // цикл, принимающих 0 по строкам { if (digitalRead(PinIn) == LOW) // если один из указанных портов входа равен 0, то.. { Serial.println(value); // то b равно значению из двойного массива delay(175); } } digitalWrite(PinOut, HIGH); // подаём обратно высокий уровень } } void loop() { matrix(); // используем функцию опроса матричной клавиатуры }

С использованием библиотеки считывание данных с цифровой клавиатуры упрощается.

#include const byte ROWS = 4; const byte COLS = 3; char keys = { {"1","2","3"}, {"4","5","6"}, {"7","8","9"}, {"#","0","*"} }; byte rowPins = {5, 4, 3, 2}; byte colPins = {8, 7, 6}; Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); void setup(){ Serial.begin(9600); } void loop(){ char key = keypad.getKey(); if (key != NO_KEY){ Serial.println(key); } }

Сегодня про так называемую резистивную клавиатуру или как подключить много кнопок на один аналоговый вход. Для этого был собран вот такой модуль, на котором 5 кнопок и несколько SMD резисторов, а так же 3 штырька для питания и выхода.

В общем как это все устроено.

Я надеюсь все знают как работает делитель напряжения. Есть 2 резистора подключенных последовательно в цепь питания и от средней точки этих резисторов снимается напряжение, величина которого зависит от падения напряжения на этих самых резисторах. А если совсем просто, то если на входе й нас 5 вольт и 2 резистора по 1кОм, то со средней точки мы будем снимать 2,5 вольт.

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

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

Это даже можно продемонстрировать. Ниже пример, который отправляет значение в serial которое считывает функцией analogread на выходе А0 к которому подключена клавиатура. Когда ничего не нажато в мониторе порта будет 1023, если надавить на кнопку это значение будет отличаться и зависеть от нажатой кнопки.

Осталось только различать эти значения в коде без условия if здесь не обойтись, а лучше вообще это вынести в отдельную функцию. К примеру эта функция будет key() и возвращает она байт

Byte key(){ int val = analogRead(0); // считываем значение с аналогового входа в переменную val if (val < 50) return 1; // сверяем переменную, если val меньше 50 возвращаем 1 (первая кнопка) else if (val < 150) return 2; // если val меньше 150 вторая кнопка и т.д. else if (val < 350) return 5; else if (val < 500) return 4; else if (val < 800) return 3; else return 0; // если ничего не подошло возвращаем 0 }

Void loop() { int sensorValue = analogRead(A0); // считываем значения с А0. Пригодится для отладки Serial .print(key()); // выводим номер кнопки в serial Serial .print(" "); Serial .println(sensorValue); // выводим значения с А0. Пригодится для отладки delay(1); // задержка между считываниями для стабильности }

Byte key(){ int val = analogRead(0); if (val < 50) return 1; else if (val < 150) return 2; else if (val < 350) return 5; else if (val < 500) return 4; else if (val < 800) return 3; else return 0; } // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial .begin(9600); } // the loop routine runs over and over again forever: void loop() { // read the input on analog pin 0: int sensorValue = analogRead(A0); // print out the value you read: Serial .print(key()); Serial .print(" "); Serial .println(sensorValue); delay(1); // delay in between reads for stability }



Рекомендуем почитать

Наверх