Клавиши Arduino с помощью кнопок, как отменить, когда использовать матрицу?
У меня есть простой набор из 8 кнопок, подключенных к плате Teensy 3.2 (которая использует Arduino через плагин Teensyduino). 8 кнопок находятся на контактах 1-8, а их общая линия заземления (одна линия припаяна к каждой из них) находится на выводе GND. У меня есть код, чтобы заставить работать любую кнопку. В данный момент установлено нажатие второй кнопки типа "А".
Я бы хотел, чтобы кнопки 1-8 печатались на A,B,C... и т. Д. Соответственно, когда вы их нажимаете. Мне сообщили о двух проблемах с моей настройкой, первая из которых заключается в том, что копирование кода для каждой кнопки является плохим способом решения этой проблемы, а во-вторых, что она подвержена подпрыгивающим проблемам (создает нажатие клавиши один раз каждые 5 нажатий или около того). Я также хотел бы настроить это так, чтобы в будущем я мог написать стороннее приложение, которое настраивает ключи на основе предпочтений пользователя.
Добавление этих потребностей, я не уверен, куда идти дальше. Я достаточно новичок, поэтому я не уверен, как правильно включить класс отказов или если это правильный путь, учитывая потребности.
Матрица - это путь, или есть элегантный способ ручной настройки каждой кнопки и компенсации отказов? Спасибо ~ Текущий код следует:
#define CHECK_EVERY_MS 20
#define MIN_STABLE_VALS 5
unsigned long previousMillis;
char stableVals;
char buttonPressed;
void setup() {
// make pin 2 an input and turn on the
// pullup resistor so it goes high unless
// connected to ground:
pinMode(2, INPUT_PULLUP);
Keyboard.begin();
}
void loop() {
if ((millis() - previousMillis) > CHECK_EVERY_MS)
{
previousMillis += CHECK_EVERY_MS;
if (digitalRead(2) != buttonPressed)
{
stableVals++;
if (stableVals >= MIN_STABLE_VALS)
{
buttonPressed = !buttonPressed;
stableVals = 0;
if (buttonPressed)
{
//Send an ASCII 'A',
Keyboard.write(65);
}
}
}
else
stableVals = 0;
}
}
---------ИЗМЕНЕНИЕ КОДА 1
#include <Bounce2.h>
// Instantiate a Bounce object
Bounce debouncer[8];
bool prevValues[8];
// Keyboard values for btn 1 2 3 4 5 6 7 8
char keyboardValues[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
void setup() {
// First setup all the pins as input with pullup
pinMode(BUTTON_PIN_1,INPUT_PULLUP);
pinMode(BUTTON_PIN_2,INPUT_PULLUP);
pinMode(BUTTON_PIN_3,INPUT_PULLUP);
pinMode(BUTTON_PIN_4,INPUT_PULLUP);
pinMode(BUTTON_PIN_5,INPUT_PULLUP);
pinMode(BUTTON_PIN_6,INPUT_PULLUP);
pinMode(BUTTON_PIN_7,INPUT_PULLUP);
pinMode(BUTTON_PIN_8,INPUT_PULLUP);
// Setup Bounce instance - First attach them to the debouncer
debouncer[0].attach(BUTTON_PIN_1);
debouncer[1].attach(BUTTON_PIN_2);
debouncer[2].attach(BUTTON_PIN_3);
debouncer[3].attach(BUTTON_PIN_4);
debouncer[4].attach(BUTTON_PIN_5);
debouncer[5].attach(BUTTON_PIN_6);
debouncer[6].attach(BUTTON_PIN_7);
debouncer[7].attach(BUTTON_PIN_8);
Keyboard.begin();
// Then set the interval (e.g. 10 ms)
unsigned char i;
for (i = 0; i < 8; i++)
prevValues[i] = 0;
}
void loop() {
// Update the Bounce instances
unsigned char i;
for (i = 0; i < 8; i++)
debouncer[i].update();
bool debounced_btn_1 = debouncer[0].read();
bool debounced_btn_2 = debouncer[1].read();
bool debounced_btn_3 = debouncer[2].read();
bool debounced_btn_4 = debouncer[3].read();
bool debounced_btn_5 = debouncer[4].read();
bool debounced_btn_6 = debouncer[5].read();
bool debounced_btn_7 = debouncer[6].read();
bool debounced_btn_8 = debouncer[7].read();
for (i = 0; i < 8; i++)
{
bool currVal = debouncer[i].read();
if ((!currVal) && (prevValues[i]))
{ // If now it is pressed (value = 0) and it wasn't before (prevvalue = 1)
Keyboard.write(keyboardValues[i]);
}
}
}
1 ответ
Как я уже говорил вам, это решение хорошо работает, если вам нужно использовать только одну кнопку. Если вам нужно больше кнопок, вы должны продублировать этот код для каждой кнопки.
Альтернативой является прямая проверка значения порта (8 битов одновременно). Я думаю, что это лучшее решение для выступлений, но оно не очень читаемо.
Решение bounce2 является лучшим, на мой взгляд. Вы просто должны
- скачать
Bounce2
библиотека и правильно установить его - используйте это в своем эскизе.
Например, вы можете использовать массив для хранения всех вышибал. Пример с 8 выводами:
#include <Bounce2.h>
// Instantiate a Bounce object
Bounce debouncer[8];
void setup() {
// First setup all the pins as input with pullup
pinMode(BUTTON_PIN_1,INPUT_PULLUP);
pinMode(BUTTON_PIN_2,INPUT_PULLUP);
...
// After setting up the button, setup the Bounce instance
// First attach them to the debouncer
debouncer[0].attach(BUTTON_PIN_1);
debouncer[1].attach(BUTTON_PIN_2);
...
// Then set the interval (e.g. 10 ms)
unsigned char i;
for (i = 0; i < 8; i++)
debouncer[i].interval(10);
// other initializations
...
}
void loop() {
// Update the Bounce instances
unsigned char i;
for (i = 0; i < 8; i++)
debouncer[i].update();
// From now on you can access the debounced
// values directly from the array, for instance
bool debounced_btn_1 = debouncer[0].read();
bool debounced_btn_8 = debouncer[7].read();
...
}
В вашем случае, поскольку вы хотите отправить команду клавиатуры, вы можете сохранить все значения в массиве (который, конечно, можно изменить) и затем отправлять их при необходимости; Вы также должны помнить последнее состояние для отправки значения только при нажатии кнопки...
bool prevValues[8];
// Keyboard values for btn 1 2 3 4 5 6 7 8
char keyboardValues[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
void setup() {
// Pins initializations
...
for (i = 0; i < 8; i++)
prevValues[i] = 0;
}
void loop() {
// Update the Bounce instances
...
for (i = 0; i < 8; i++)
{
bool currVal = debouncer[i].read();
if ((!currVal) && (prevValues[i]))
{ // If now it is pressed (value = 0) and it wasn't before (prevvalue = 1)
Keyboard.write(keyboardValues[i]);
}
}
...
}