[아두이노] 스위치버턴을 이용한 Keypad 제어
[아두이노] 스위치버턴을 이용한 Keypad 제어
- 온라인 가상시뮬레이터 : https://www.tinkercad.com/
- 참고자료출처 : http://playground.arduino.cc/Code/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() : 키값 읽기
그외 함수들은 참고출처에 가셔서 한번 읽어보시길 바래요.
설계
- 스위치 버턴으로 읽기
- 아두이노 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를 쳐보세요 만들고 싶은 충동이 느껴질꺼에요.
'IOT > 아두이노' 카테고리의 다른 글
[아두이노] Processing을 이용한 아두이노 제어 I (0) | 2019.03.10 |
---|---|
[아두이노] 온도센서(TMP36) 제어 (0) | 2019.03.09 |
[아두이노] Keypad 제어 (0) | 2019.03.07 |
[아두이노] GAS Sensor (0) | 2019.03.02 |
[아두이노] 타이머를 이용한 인터럽트(Interrupt) 제어 (0) | 2019.03.01 |