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

Тема в разделе "Глядите, что я сделал", создана пользователем Arduiner001, 20 июн 2015.

  1. Arduiner001

    Arduiner001 Гик

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

    kbd_init() Возвращаемое значение: нет.
    Выполняет инициализацию

    kbd_read() Возвращаемое значение: char.
    Собственно считывает данные. Возвратит пробел, если никакая клавиша не нажата

    Код инита:
    Код (Text):
    void kbd_init(){
      for(int i = 0; i < 4; i++){
        pinMode(sendPins[i], OUTPUT);
      }
      for(int i = 0; i < 4; i++){
        pinMode(receivePins[i], INPUT);
      }
    }
    Код считывания:
    Код (Text):
    char kbd_read(){
      char btn;
      btn = ' ';
      for(int i = 0; i < 4;i++){
        digitalWrite(sendPins[i], LOW);
      }
      digitalWrite(sendPins[3], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = '1';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = '4';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = '7';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = '*';
      }
      digitalWrite(sendPins[3], LOW);
      digitalWrite(sendPins[2], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = '2';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = '5';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = '8';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = '0';
      }
      digitalWrite(sendPins[2], LOW);
      digitalWrite(sendPins[1], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = '3';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = '6';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = '9';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = '#';
      }
      digitalWrite(sendPins[1], LOW);
      digitalWrite(sendPins[0], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = 'A';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = 'B';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = 'C';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = 'D';
      }
      digitalWrite(sendPins[0], LOW);
      return btn;
    }
    Стоит отметить, что в начале кода обязаны быть массивы с номерами пинов. Пример для уны:
    Код (Text):
    int sendPins[4] = {2, 3, 4, 5};
    int receivePins[4] = {6, 7, 8, 9};
    Массивы должны быть с такими же именами!

    А теперь пример, кодовый замок:
    Код (Text):
    #include <Servo.h>

    int sendPins[4] = {2, 3, 4, 5};
    int receivePins[4] = {6, 7, 8, 10};
    int pos = 0;
    int nP = 0;
    char pass[4] = {'A', 'B', '0', '3'};     //Это - правильный пароль
    char writing[4];                            //Это - пароль, который ввёл пользователь

    Servo door;

    void setup() {
      pinMode(12, OUTPUT);
      pinMode(11, OUTPUT);
      kbd_init();
      door.attach(9);
      door.write(0);
    }

    void loop() {
      char sym = kbd_read();
      if(sym != ' '){
        writing[pos] = sym;
        pos++;
        if(pos == 4){
          if(writing[0] == pass[0] && writing[1] == pass[1] && writing[2] == pass[2] && writing[3] == pass[3]){
            digitalWrite(11, HIGH);
            delay(100);
            digitalWrite(11, LOW);
            pos = 0;
            door.write(180);
            delay(5000);
            door.write(0);
            nP = 0;
          } else {
            digitalWrite(11, HIGH);
            delay(100);
            digitalWrite(11, LOW);
            delay(100);
            digitalWrite(11, HIGH);
            delay(100);
            digitalWrite(11, LOW);
            delay(100);
            digitalWrite(11, HIGH);
            delay(100);
            digitalWrite(11, LOW);
            pos = 0;
            door.write(0);
            nP++;
          }
        }
        delay(500);
      }
      if(nP == 4){
        digitalWrite(12, HIGH);
        delay(100);
        digitalWrite(11, HIGH);
        delay(100);
        digitalWrite(11, LOW);
        delay(100);
        digitalWrite(11, HIGH);
        delay(100);
        digitalWrite(11, LOW);
        delay(120000);
        digitalWrite(12, LOW);
        nP = 0;
      }
    }

    void kbd_init(){
      for(int i = 0; i < 4; i++){
        pinMode(sendPins[i], OUTPUT);
      }
      for(int i = 0; i < 4; i++){
        pinMode(receivePins[i], INPUT);
      }
    }

    char kbd_read(){
      char btn;
      btn = ' ';
      for(int i = 0; i < 4;i++){
        digitalWrite(sendPins[i], LOW);
      }
      digitalWrite(sendPins[3], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = '1';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = '4';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = '7';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = '*';
      }
      digitalWrite(sendPins[3], LOW);
      digitalWrite(sendPins[2], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = '2';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = '5';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = '8';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = '0';
      }
      digitalWrite(sendPins[2], LOW);
      digitalWrite(sendPins[1], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = '3';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = '6';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = '9';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = '#';
      }
      digitalWrite(sendPins[1], LOW);
      digitalWrite(sendPins[0], HIGH);
      if(digitalRead(receivePins[3]) == 1){
        btn = 'A';
      }
      if(digitalRead(receivePins[2]) == 1){
        btn = 'B';
      }
      if(digitalRead(receivePins[1]) == 1){
        btn = 'C';
      }
      if(digitalRead(receivePins[0]) == 1){
        btn = 'D';
      }
      digitalWrite(sendPins[0], LOW);
      return btn;
    }
     
    Последнее редактирование: 20 июн 2015
  2. DrProg

    DrProg Вечный нерд

    Я сначала тоже сделал через 8 цифровых пина, но потом решил, что экономнее будет через 4 аналоговых:

    Код (Text):
    #define BOOZ 12

    const int A[] = {A0, A1, A2, A3};
    int P; // нажатый столбец
    int M; // нажатая строка
    int an; // показание активного пина

    // символы на клаве
    const char k4x4 [4][4] = {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };


    void setup() {
      for (int i = 0; i <= 3; i++) {
        pinMode(A[i], INPUT);
      }
      pinMode(BOOZ, OUTPUT);

      Serial.begin(9600);
    }

    void loop() {
      //  по кругу опрашиваем аналоговые пины (столбцы), если на каком то из них показание менее 1000, значит есть нажатие

      for (int i = 0; i <= 3; i++) {
        an = analogRead(A[i]);
        if (an > 20) {

          M = i; // определили номер нажатого столбца
          // далее по значению напряжения вычисляем номер строки
          // резисторы на выходящих ножках притянутые к земле установил в порядке убывания: 100кОм, 33кОм, 10кОм и 1КОм, что соответсвтует примерным значениям на пинах 500, 250, 100, 10
          // на всех входящих ножках установлены резисторы 100кОм
          // так как показания немного колеблются, берем диапазон с запасом:

          if (an > 800)  {
            P = 0;
          } else if ((an > 400) && (an < 450)) {
            P = 1;
          } else if ((an > 200) && (an < 260)) {
            P = 2;
          } else if (an > 100)  {
            P = 3;
          }
          char a = k4x4[P][M]; // считываем соответствующий символ для комбинации столбца и строки
          Serial.print(a);
              tone(BOOZ, 200, 10); // подтверждаем писком введенный символ
          while (analogRead(A[i]) > 20 ); // ждем отжатия кнопки
        }
      }

    }
    Написано в теле лупа, можно легко загнать в функцию при желании.

    Второй вариант сделал из цепочки четырех одинаковых резисторов на 220Ом, получилось изящнее и проще.
     
    Последнее редактирование: 20 июн 2015
  3. Arduiner001

    Arduiner001 Гик

    Согласен!
    А ещё можно из обычной клавы сделать резистивную, например так:

    (Жёлтые проводки - к клаве)
    [​IMG]
     
    Последнее редактирование: 20 июн 2015