// 구글 검색 // 네이버 검색

지난 글에서 설명한 이론을 바탕으로 이번에는 단일 스위치에서 시작해 스위치 매트릭스까지 한단계씩 확장해가며 키보드에 사용할 회로를 만들어 보겠습니다.

 

접지 라인 통합

아두이노에 스위치를 하나만 연결한다면 아래 그림의 왼쪽처럼 회로를 구성할 수 있습니다. 스위치 2개를 독립적으로 연결한다면 가운데 회로처럼 구성할 수 있겠지요. 그리고 스위치를 접지하는 라인은 전선이 전류를 견딜 수 있다면 하나로 통합해도 문제가 없습니다. 따라서 아래 그림의 오른쪽처럼 회로를 변경할 수 있습니다.

그림 1. 스위치 병렬 연결

이번에 키보드를 만들때 사용할 아두이노 호환보드는 digitalRead()로 전압을 읽을 수 있는 GPIO 단자가 18개 뿐입니다. 모든 단자를 입력을 감지하는데 사용한다면, 위 방식으로 회로를 구성할 경우 총 18개의 스위치를 사용할 수 있습니다. 하지만 이번에 만들 키보드는 총 90개의 스위치를 사용해야 하기 때문에, 더 많은 스위치를 사용할 수 있도록 다른 방식으로 회로를 구성해보도록 합시다.

 

매트릭스 구성

그림 2. 스위치 매트릭스

먼저 위 회로에서 하나의 접지 라인에 2개의 스위치를 연결한 것 처럼, 각 행마다 2개의 스위치를 연결해봅시다. 하지만 한 행에 연결된 스위치 중 어떤것을 눌러도 똑같이 접지 라인으로 연결되기 때문에 어떤 스위치를 눌러졌는 지 구분할 수 없습니다. 그렇다면 각 열 라인을 구분해주기 위해, 먼저 행 라인처럼 접지단자가 아닌 GPIO 단자에 연결해줍니다. 그리고 열 라인을 연결해준 단자의 모드를 Output으로 설정합니다. 그러면 digitalWrite()함수를 통해 Low를 출력하면 0V가 공급되므로 접지에 연결한 것 처럼, High를 출력하면 5V가 공급되므로 VCC에 연결한 것 처럼 생각해 각 열 라인을 구분할 수 있습니다. 스위치 입력을 감지하고자 하는 열을 Low로 나머지 열을 High를 설정하고 각 행의 전압을 읽는 것으로 해당 열의 스위치 입력 상태를 감지할 수 있습니다. 아래 표는 열 1이 Low, 열 2가 High 일 때 스위치 입력에 따라 각 행의 전압을 digitalRead()로 읽은 결과를 정리한 것입니다.

스위치 11 스위치 12 스위치 21 스위치 22 행 1 행 2
1 1
0 1
1 1
1 0
1 1
0 1
0 0
0 1
1 0
1 1
1 0
0 0
0 0
0 0
0 0
0 0

스위치 11일 눌러진 경우 행 1이 0으로, 스위치 21이 눌러진 경우 행 2가 0이 되며, 스위치 12와 스위치 22는 하나씩 눌러진 경우 결과에 아무런 영향을 주지 않습니다. 하지만 두 스위치가 동시에 눌러진 상태로 다른 스위치를 누를 경우 문제가 발생하는데, 누르지 않은 스위치가 눌러진 것 처럼 원하지 않은 결과가 나오는 것입니다.

 

다이오드 추가

이를 보통 고스트 키 현상이라 부릅니다. 원인은 스위치 입력에 따라 회로의 다른 경로를 우회해 전류가 흘러가 마치 특정 스위치가 눌러진 것 처럼 전류가 흐르기 때문입니다. 예를 들어 아래 회로에서 스위치 21을 누른다면 Row 2 → SW21 → Col 1 순으로 전류가 흐릅니다. 또한 스위치 11, 스위치 12, 스위치 22가 눌러진 경우라면 Row 2  SW22  SW12  SW11  Col 1 순으로 전류가 흐릅니다. 두 경우 모두 중간 경로는 다르지만 Row 2에서 Col 1로 전류가 흐르게 된다는 점은 같습니다. 때문에 Col 1이 Low일 때 Row 2가 0이므로 SW21가 눌러져 있다라고 판단하는 것입니다.

그림 3. 고스트 키 현상과 해결법

해결하는 방법은 간단한데 우회해서 전류가 흐르지 않도록 다이오드를 추가해 주는 것입니다. 다이오드는 전류를 한쪽 방향으로만 흐르게 해주는 소자이므로 스위치 앞이나 뒤에 추가하면 전류가 우회해서 흐르지 못하게 할 수 있습니다. 위 그림의 오른쪽 회로를 보면 Row 2에서 흐르기 시작한 전류가 SW12 앞에 있는 다이오드에 의해 차단되 Col 1로 흐르지 못하는 것을 알 수 있습니다. 추가로 Col 2에서 Col 2로 저항 없이 연결되어 과전류로 인해 보드가 망가지는 것 도 방지할 수 있습니다. 과전류는 보드와 Col 라인 사이에 100~200Ω 정도의 저항을 연결해 주는 것으로 해결할 수 있지만 다이오드를 추가해 주었다면 생략해도 무방합니다.

 

여기까지 구성한 회로를 9행 9열로 확장하면 최대 81(=9x9)개의 스위치를 사용할 수 있습니다. 키패드나 포커배열 키보드라면 이정도로 충분하지만 사용할 수 있는 스위치가 아직 90개가 안되기 때문에 한단계 더 확장해 보도록 합니다.

 

스위치와 합성저항

지난 글에서도 설명했듯이 아두이노로 스위치의 상태를 판별하는 방법은 스위치에 걸린 전압을 측정하는 것입니다. 정확히는 스위치를 저항으로 간주하고 스위치 앞 지점과 지면(GND) 사이에 걸리는 전압을 측정하는 것입니다. 매트릭스 회로라면 특정 행과 특정 열 사이에 걸리는 전압을 측정하는 것입니다. 이때 측정되는 전압은 저항값에 따라 달라지며, 저항값은 스위치와 저항을 적절하게 연결하는 것으로 바꿀 수 있습니다. 아래 그림은 위 회로에서 스위치와 다이오드를 병렬연결해서 2개로 늘려주고 저항을 추가한 회로입니다.

그림 4. 스위치와 저항의 병렬연결로 연결한 회로

 

위 회로는 불필요하게 저항이 많이 들어가 키보드에 배치할 공간이 부족하므로 같은 크기의 저항을 사용하는 라인을 통합해 정리해 주었습니다.

그림 5. 같은 저항을 사용하는 라인을 통합한 회로

 

그리고 키보드에 사용할 수 있도록 스위치별로 분리해 한번 더 정리해 주었습니다.

그림 6. 스위치별로 분리한 회로

 

위 회로는 이제 행의 전압을 읽을 때 digitalRead()가 아니라 analogRead() 함수를 사용해야 하며, analogRead() 함수는 모든 포트에서 사용할 수 없기 때문에, 각 행 라인은 아날로그 읽기를 지원하는 포트에 연결해 주어야 합니다. 핀아웃을 확인해 보면 4, 6, 8, 9, 10, 18, 19, 20, 21의 총 9개 포트에서 아날로그 읽기를 지원하고 있습니다. 열 라인은 GPIO 포트 아무곳에나 연결해도 상관없지만 행 라인은 반드시 아날로그 포트에 연결해 주시기 바랍니다. 미지원 포트에 연결한 경우 analogRead()로 전압을 읽어도 무의미한 쓰레가 값을 반환합니다.

 

완성

그림 7. 완성된 회로도

위 그림은 최종적으로 사용할 회로도입니다. 실제로 소자를 배치할 모습과 최대한 비슷하게 그렸습니다. 최대 108(= 6행 x 6열 x 3저항)개의 스위치를 사용할 수 있는 회로입니다. 저항의 크기는 구매할 수 있는 것들 중에서 적당한 것으로 골랐습니다.

+ Recent posts