Проблема при кодировании обнаружения клавиш клавиатуры 4x4 (без библиотеки)

Часть моего текущего задания включает в себя чтение ввода с клавиатуры 4x4, подключенной к Arduino UNO. Хотя это можно легко сделать с помощью <Keypad.h>, проект выполняется с помощью онлайн-симулятора Tinkercad, а это означает, что у меня нет доступа к этой библиотеке. Мне придется сделать это вручную.

Вот код, который у меня есть на данный момент:

#include <Wire.h>
#define DIMENSIONS 4
const unsigned long period = 50;
unsigned long prevMillis = 0;
byte modo = 0;
const byte rowsPins[DIMENSIONS] = {11, 10, 9, 8};
const byte columnsPins[DIMENSIONS] = {7, 6, 5, 4};
char keys[DIMENSIONS][DIMENSIONS] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

void setup()
{
    Serial.begin(9600);//отладка
    for(byte i = 0; i < DIMENSIONS; i++){
        pinMode(columnsPins[i], INPUT);
        digitalWrite(columnsPins[i], HIGH);
        pinMode(rowsPins[i], INPUT_PULLUP);
    }
    Wire.begin();
}

void loop()
{
    switch(modo){
        case 0:
            Serial.print("Master (2) boot up\n");
            modo++;
            break;
        case 1:
            if(millis() >= 1000){
                modo++;
            }
            break;
        case 2:
            if (millis() - prevMillis > period){
                prevMillis = millis();
                for(byte c = 0; c < DIMENSIONS; c++){
                    pinMode(columnsPins[c], OUTPUT);
                    digitalWrite(columnsPins[c], LOW);
                    for(byte r = 0; r < DIMENSIONS; r++){
                        if(digitalRead(columnsPins[r]) == LOW){
                            Serial.println(keys[r][c]);
                        }
                    }
                    digitalWrite(columnsPins[c], HIGH);
                    pinMode(columnsPins[c], INPUT);
                }
            }
            break;
        default:
            break;
    }
}

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

Теоретически этот код должен считывать ввод с подключенной клавиатуры 4x4, а затем печатать на последовательном мониторе, какая клавиша была нажата. Я провел немало поисков, и другие решения для обнаружения нажатий клавиш без библиотеки клавиатуры не сильно отличаются от того, что я сделал здесь. Однако по какой-то причине то, что я написал, у меня не работает должным образом.

При запуске моделирования последовательный монитор непрерывно и циклично печатает 1, 5, 9, D. Нажатие клавиш иногда печатает соответствующий символ, но это не останавливает поток 1, 5, 9 и D.

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

, 👍3

Обсуждение

вы можете добавить массив 4x4 для хранения состояния кнопки... затем выполнять задержку устранения дребезга на 50 мс всякий раз, когда состояние кнопки изменяется, @jsotola


1 ответ


Лучший ответ:

5

В случае 2:

digitalWrite(columnsPins[c], LOW);
for(byte r = 0; r < DIMENSIONS; r++){
   if(digitalRead(columnsPins[r]) == LOW){
   Serial.println(keys[r][c]);
   }
}

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

,

Не могу поверить, что не заметил столь очевидной ошибки. Спасибо за сохранение, Delta_G., @Maf95

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

@Гил не клавиатура, а просто скромная клавиатура 4x4. [Вот](https://imgur.com/a/oQCJerV). Это чрезвычайно просто: контакты Arduino подключены напрямую к клавиатуре, поэтому я не счел необходимым включать его в OP., @Maf95

@ Maf95 «Когда программисту трудно найти ошибку, это потому, что он ищет не в том месте»., @Mark Morgan Lloyd