[아두이노] 스위치버턴을 이용한 Keypad 제어

IOT/아두이노|2019. 3. 8. 09:00

[아두이노] 스위치버턴을 이용한 Keypad 제어



오늘은 KeyPad의 내부 동작을 살펴보도록 하죠. 가장 잘 알려진게 스위치버턴으로 표현한 예제입니다. 아래 스위치 버턴의 연결한 회로도를 잘 살펴보세요. 이 원리를 이해하시면 나중에 3x3x3 LED CUBE를 만드는데 활용되는 원리니깐 꼭 이해해 주세요.

1. 스위치버턴을 이용한 KeyPad



스위치 버턴은 기본 눌렀을때 전류가 흐르잖아요. 이걸 16개의 버턴을 연결한 것이죠. 그리고 각 스위치 버턴의 입력을 내부풀업저항을 이용해서 스위치 누른 위치의 상태값을 통해서 몇번째 스위치가 눌러졌는지 알게 됩니다.


우선 선 4x4 스위치 버턴을 배치한뒤에 선을 그림과 같은 형태로 연결하세요. 그리고 스위치 버턴에 내부풀업저항을 이용한다고 가정해 봅시다. 여기서, 가로 라인을 1층으로 생각하시고 세로는 각 호실이라고 했을 때 그러면 1층 2호실을 눌렀을 경우를 생각해보세요.

어떤 경우에 1층 2호실이 눌러졌는지 알 수 있을까요.


하나만 쪼개서 다시 살펴보세요. 1층 2호실은 6번핀이 Gnd이고 4번핀은 LOW 상태일때 입니다. 좀 햇갈리 수 있는데 내부풀업저항 모드일대는 초기 스위치 값은 HIGH(1)인 상태가 되고 스위치를 누르면 전류가 흘러 가기 때문에 해당 4번핀은 LOW(0) 상태가 됩니다. 결론은 1층 2호실 스위치를 누르면 6번핀이 Gnd일때 4번핀의 입력핀이 LOW일때입니다.

이걸 어떻게 찾아내느냐 하면

  for(int y=0;y<rows;y++){
    digitalWrite(rowPins[y], LOW);   
    for(int x=0;x<cols;x++){     
        if(!digitalRead(colPins[x]))val = keys[y][x];
    }        
    digitalWrite(rowPins[y], HIGH);      
  
  }

2중 for문을 이용해서 각 층별에 대한 해당 호별로 순차적으로 체크하면 됩니다. 초기로 모든 층은 HIGH 상태로 세팅한 후에
1층(LOW)부터서 1호실, 2호실, 3호실, 4호실 체크해서 스위치가 눌러졌는지 확인한 뒤에 1층은 HIGH로 다시 잠궈집니다.
2층(LOW)부터서 1호실, 2호실, 3호실, 4호실 체크해서 스위치가 눌러졌는지 확인한 뒤에 2층은 HIGH로 다시 잠궈집니다.
...
이렇게 초기값으로 각 층은 HIGH로 해놓으면 LOW로 된 층의 각 호실만 체크할 수 있게 됩니다.

설명이 어려울 수 있는데 쉽게 말해서 HIGH은 각 층이 닫혀진 상태이고 LOW되면 LOW된 층이 개방되게 됩니다.

만약에 각 층이 전부다 LOW라고 생각해보세요. 가령 2층 1호실을 눌렀습니다. 그러면 5번 핀은 digitalRead(5)핀의 값은 LOW가 됩니다. 하지만 누른 위치가 1층 1호실인지 2층 1호실인지 알 수 없게 됩니다. 만약 for문이 1층부터 체크한다면 1층 1호실에서 출력값이 LOW되기 때문에 1층 1호실로 인식하게 되고 만약에 for문이 4층부터 순차적으로 체크했다면 4층 1호실에서 LOW가 되기 때문에 4층 1호실로 인식하게 됩니다.

각 층을 체크할때는 체크하는 층만 LOW가 되고 나머지 층은 HIGH로 잠궈놔야 됩니다.

이해가 안되시면은 그냥 HIGH일때 잠겨지고 LOW일때 열린다고 생각하시면 되겠습니다. 이게 스위치에 전류의 흐름을 이해하면 쉽게 이해되는데 약간 설명이 어렵네요.

만약 1층(6번)이 HIGH일때 1층 1호실을 누르나 안누르나 1층 1호실 digitalRead(5)의 출력값은 무조건 HIGH입니다. 스위치를 누른다고 LOW되지 않습니다. 1층(6번) 핀이 LOW일때 누른 호실의 digitalRead(호실)의 출력값이 그제서아 LOW 됩니다.
풀업저항스위치버턴의 기본 동작을 이해하셔야 이 원리를 이해하실 수 있습니다.

2. 회로도 구성


  • 준비물 : 스위치버턴 16개, 아두이노우노
  • 내용 : 키를 누르면 그 값을 시리얼모니터로 출력할거기 때문에 간단히 회로도 구성함.


선 연결만 주의하시면 그럽게 어렵지 않습니다.

3. 코딩


  • 사용함수 : Serial.begin(), Serial.println(), keypad.getKey()
  • 내용 : Keypad에 누른 값을 아두이노 IDE의 시리얼 모니터로 간단히 출력하자.
  • 참고출처 : http://playground.arduino.cc/Code/Keypad

복습

  • Serial.begin(9600) : 시리얼 통신 시작
  • Serial.println(출력값) : 출력값을 시리얼 모니터로 출력
  • keypad.getKey() : 키값 읽기

그외 함수들은 참고출처에 가셔서 한번 읽어보시길 바래요.

설계

  1. 스위치 버턴으로 읽기
  2. 아두이노 IDE 시리얼모니터로 키 값 출력한다.

코딩을 전체적으로 하면

#include <Keypad.h>

const byte rows = 4; //four rows
const byte cols = 4; //four columns

byte rowPins[rows] = {9,8,7,6};
byte colPins[cols] = {5,4,3,2};

char keys[rows][cols] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

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);
   }
}

4. 라이브러리 없이 코딩


스위치버턴 Keypad에서 설명한 방식으로 코딩을 하면 제블러그에 있던 코딩인데 그대로 인용합니다. 로직을 자세히 살펴보시면 이해가 되실꺼에요.

const byte rows = 4; //4 rows
const byte cols = 4; //4 columns

byte rowPins[rows] = {9,8,7,6};
byte colPins[cols] = {5,4,3,2};

 char keys[rows][cols] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

void setup(){
  Serial.begin(9600);
  
  for(int i=0;i<rows;i++){
    pinMode(rowPins[i], OUTPUT);
    digitalWrite(rowPins[i], HIGH);   // 각층 초기화로 잠금
  }
  for(int i=0;i<cols;i++){
    pinMode(colPins[i], INPUT_PULLUP); //각호실 내부풀업저항모드로 읽기
  }  
}

void loop(){
  
  char val = '\0';
 
  for(int y=0;y<rows;y++){
    digitalWrite(rowPins[y], LOW);   //해당층 개방
    for(int x=0;x<cols;x++){     
        if(!digitalRead(colPins[x]))val = keys[y][x];
    }        
    digitalWrite(rowPins[y], HIGH);  //해당층 잠금
  
  }

 if(val!='\0'){
    Serial.println(val);
   delay(300);
 }      
}

5. 결과


선 배치가 제일 귀찮았네요.


마무리


오늘은 Keypad를 스위치버턴으로 대신 했습니다. 그리고 라이브러리 없이 직접 코딩을 사용하여 동작을 제어 했네요.

스위치버턴에서 층과 호실에 관한 전류 흐름의 체크에 대해서 꼭 이해해 주세요. 왜냐면 나중에 응용편에서 거론한 3x3x3 LED CUBE에 원리가 같습니다.

원래 LED 제어를 한뒤에 응용편으로 미리 다루어야 했는데 응용편이고 코딩쪽이여서 다소 어려울 수 있어서 스위치버턴에서 먼저 그 원리를 사용하게 되었네요.
꼭 층과 호실의 관계를 이해해 주세요. 입력을 층과 호실로 받았지만 반대로 출력을 층과 호실로 보낼 수 있습니다. 그게 바로 3x3x3 LED CUBE의 기본 원리입니다.

이 원리를 깨우치면 진짜 화려하고 재밌는 작품을 만들 수 있으니깐 꼭 이해해 주세요.

궁금하시면 구글검색으로 3x3x3 LED CUBE를 쳐보세요 만들고 싶은 충동이 느껴질꺼에요.


댓글()

[아두이노] Keypad 제어

IOT/아두이노|2019. 3. 7. 09:00

[아두이노] Keypad 제어



오늘은 간단히 KeyPad를 사용하는 법을 살펴보도록 하겠습니다. 아두이노 선 연결하는 것은 별로 어렵지 않습니다. 그리고 Keypad 라이브러리만 잘 연결하면 딱히 사용하는 것도 어렵지 않고 쉽게 사용 가능합니다. 이번 포스팅은 아주 간단한 내용입니다.

1. KeyPad



총 8개의 핀으로 구성되어 있으며 내부 구조는 다음 포스팅에 설명하겠지만 우선은 간단히 가로4핀 x 세로4핀으로 선이 연결되었다고 생각하시면 됩니다. 4x4로 행과 열을 나타낸다고 생각하시면 됩니다. 우선 배열로 KeyPad[4][4]로 생각하시면 될 듯요.
핀 연결은 아두이노 디지털핀 아무곳이나 8핀을 연결하시면 돼요.

2. 회로도 구성


  • 준비물 : KeyPad, 아두이노우노
  • 내용 : 키를 누르면 그 값을 시리얼모니터로 출력할거기 때문에 간단히 회로도 구성함.


진짜로 간단하지요. 그냥 순서대로 0부터 7핀으로 아두이노에 그냥 Keypad를 붙이여 연결되어 버립니다. 하지만 그렇게 하지 않고 2번핀부터 연결했습니다. 왜냐면 시리얼통신으로 그 결과를 출력하기 때문에 시리얼통신을 담당하는 0, 1핀 때문에 Keypad가 0, 1핀에 연결된 위치값이 가상시뮬레이터에서 작동을 하지 않습니다. 그래서 어쩔 수 없이 회로도 그림처럼 연결해야겠죠.

3. 코딩


  • 사용함수 : Serial.begin(), Serial.println(), keypad.getKey()
  • 내용 : Keypad에 누른 값을 아두이노 IDE의 시리얼 모니터로 간단히 출력하자.
  • 참고출처 : http://playground.arduino.cc/Code/Keypad

복습

  • Serial.begin(9600) : 시리얼 통신 시작
  • Serial.println(출력값) : 출력값을 시리얼 모니터로 출력
  • keypad.getKey() : 키값 읽기

그외 함수들은 참고출처에 가셔서 한번 읽어보시길 바래요.

설계

  1. KeyPad 읽기
  2. 아두이노 IDE 시리얼모니터로 키 값 출력한다.

KeyPad를 사용하기 위해서는 가상시뮬레이터에서는 제공됩니다

#include <Keypad.h>

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

이렇게 KeyPad 클래스의 변수를 선언합니다.

Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
Keypad(키값배열, 열핀, 행핀, 열수, 행수);

Keypad의 출력할 키값 keys[4][4]로 전부 사용할 예정입니다. 그 값을 생성자 함수를 통해서 사전에 미리 만들어 놓게 됩니다. 즉, Keypad를 누른다고 알아서 그 값을 찍어주는게 아니라 출력할 값을 미리 지정해놓은 출력값과 사용할 행과 열의 핀과 행과 열의 숫자를 Keypad 객체변수를 선언할때 인자로 넘겨주게 됩니다.

이렇게 함으로써 특정 행과열 위치의 key를 누르면 keys[4][4] 해당된 위치의 값을 출력으로 나오게 됩니다.

여러 함수들이 있는데 여기에서는

keypad.getKey();

이 함수를 통해서 눌러진 키 값을 읽어오게 됩니다.

코딩을 전체적으로 하면

#include <Keypad.h>

const byte rows = 4; //four rows
const byte cols = 4; //four columns

byte rowPins[rows] = {9,8,7,6};
byte colPins[cols] = {5,4,3,2};

char keys[rows][cols] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

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);
   }
}

4. 결과


그냥 선만 대충 순서대로 연결하면 끝나고 그 결과는 위 코딩을 복사해서 시뮬레이터를 돌리면 아두이노 IDE 시리얼모니터에 키값이 출력되는걸 확인하실 수 있을꺼에요.

마무리


오늘은 Keypad를 라이브러리를 사용해서 Keypad 클래스 변수를 선언하고 이 클래스 안에 키를 읽어오는 함수를 이용해서 키가 눌렀을때 키값을 가져오게 됩니다.

그냥 선 연결을 잘하고 Keypad 클래스 변수 선언과 읽을 함수명만 기억하시면 쉽게 Keypad를 사용하실 수 있을꺼에요.

이걸 이용하면 가령 LCD16x2에 붙이면 키로 누른걸 LCD16x2로 출력시킬 수 있겠죠. 그러면 계산기를 만들고 싶은 충동이 안느껴지나요. LCD16x2 (LiquidCrystal) 제어(아두이노) 이걸 다시 보시고 회로도를 수정하시고 계산기를 한번 연구를 해보세요.


댓글()