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

본격적으로 키보드 만들기에 들어가기 전에, 간단한 키패드를 만들어 보면서 전체적인 흐름을 알아보도록 합시다.

 

1. 레이아웃 디자인과 키캡 고르기

우선 자신이 만들 키보드의 키 배치를 생각해보고, 사용할 키캡을 선택합니다.

표준 배열을 사용한다면 대부분의 키캡을 사용할 수 있지만, 자신만의 배열을 사용할 거라면 그 배열을 사용할 수 있는 키캡을 골라줍니다. 해당 배열에 필요한 키가 없다면 다른 키캡을 고르거나 키캡에 맞춰 배열을 수정해줘야 합니다.

 

아래 사이트에서 간단하게 키보드 배열을 구성해보고, 이미지나 데이터 파일로 저장하거나 나중에 불러올 수 있습니다.

http://www.keyboard-layout-editor.com/

그림 1. 분필 키캡을 사용한 표준 키패드 배열 (좌: 정각 / 우: 무각)

 

2. 보강판 설계

레이아웃을 결정했으면 이제 스위치를 고정해줄 보강판을 설계할 차례입니다. 커스텀 키보드를 만든다면 일반적으로 일러스트레이터나 캐드로 도면을 만들어 가공업체에 제작을 의뢰합니다. 하지만 이번에는 오래 사용할 키패드가 아니라 연습용으로 만드는 키패드이기 때문에 적당히 집에 있는 피자박스로 보강판을 만들겠습니다. 보강판 설계를 끝내면 하우징 설계에 들어갈 순서입니다만, 이번에는 간단하게 보강판을 하우징 일체형으로 만들어 사용합니다.

그림 2. 보강판 도면
사진 3. 완성된 보강판겸 하우징

 

3. 회로 설계

보강판 설계를 끝냈으면 이제 스위치와 컨트롤러를 연결해주는 회로를 설계할 차례입니다. 이번에는 PCB를 제작하지 않고 스위치에 직접 납땜할 것이기 때문에 회로설계만 하고 아트웍과 PCB 제작은 생략합니다. 간단한 5행 4열 매트릭스 구성이며 고스트 키 방지를 위해 스위치마다 다이오드를 하나씩 달아주었습니다.

그림 4. 키패드 회로도

 

4. 준비물 구입

회로 설계까지 끝났다면 이제 필요한 재료들을 구입합니다. 아두이노를 분리할 수 있도록 만들려면, 전선 대신 핀헤더와 Female 커넥터가 달린 점퍼선을 구입하시면 됩니다. 사용하지 않을 때 분리해서 다른 용도로 사용하거나 고장났을 때 수리하기 쉽지만, 부피가 조금 커져서 내부에 더 많은 공간을 필요로 합니다.

 

재료 : 스위치, 키캡, 아두이노, 다이오드, 전선, 보강판(이번에는 골판지)

선택: 핀헤더, Female 커넥터

도구 : 인두기, 실납, 니퍼

사진 5. 준비물 (스위치, 키캡, 아두이노, 다이오드, 전선)

 

5. 보강판과 스위치, 키캡 결합

준비물이 모두 갖춰줬으면 이제 부품들으 조립해줍니다. 우선 스위치에 키캡을 끼워준 다음, 보강판에 스위치를 결합합니다. 그리고 보강판을 접어서 테이프로 마무리합니다.

사진 6. 키캡, 스위치, 보강판을 결합한 모습
사진 7. 키패드 안쪽

 

6. 스위치 회로 구성

이제 스위치와 아두이노를 연결할 회로를 만들어줍니다. 작업할 때는 아래쪽에서 위를 바라보면서 작업하기 때문에 회로도와 좌우가 반대로라는 것에 주의하면서 스위치를 전선에 연결해줍니다. 다이오드의 방향이 행→열인지, 열→행인지는 상관없지만 반드시 모두 동일한 방향으로 연결해줘야 정상 작동합니다. 다이오드 방향에 주의하면서 작업해주세요.

사진 8. 회로 연결이 완료된 모습

 

7. 아두이노와 키패드 연결

이제 키패드와 아두이노를 연결할 차례입니다. 필요하다면 아두이노에 핀헤더를 달아주고 아니라면 전선을 직접 납땜해줍니다. 이번에는 핀헤더를 달아주었습니다.

사진 9. 아두이노 마이크로 호환보드에 핀헤더를 달아준 모습

 

키패드 회로와 연결할 아두이노 핀은 입출력으로 사용할 수 있는 핀이여야 합니다. 정확한 핀 구성은 아두이노 홈페이지나 호환 보드를 구입한 사이트의 상세페이지에 나와있습니다. 아래 그림은 이번에 구입한 호환 보드의 핀 구성입니다. 4~7번 핀에 Col 1~4를 연결해 주었고, 14~19번 핀에 Row 1~5를 연결해 주었습니다.

그림 10. 아두이노 호환보드의 핀 구성

 

회로의 노출된 부분과 아두이노가 합선되지 않도록, 가림판을 하나 끼워주는 걸로 하드웨어 구성이 모두 끝났습니다.

사진 11. 아두이노와 키패드를 연결한 모습

 

8. 아두이노 IDE 설치와 펌웨어 프로그래밍

이제 하드웨어를 완성했으니 키보드로 사용하기 위한 펌웨어를 만들어줄 차례입니다. 먼저 아두이노 홈페이지에서 아두이노 IDE를 다운받아 설치한 다음 실행합니다. PC와 아두이노를 USB로 연결하고 아두이노에 불이 들어오는 것을 확인하면, 펌웨어 제작을 위한 준비는 모두 끝났습니다.

https://www.arduino.cc/en/software

 

아래는 제가 작성한 스케치 코드입니다. 아두이노 IDE에 아래 코드를 붙여놓고 업로드하시면 바로 키패드를 사용하실 수 있습니다. 해당 코드는 아두이노에 저장되기 때문에 다른 PC에 연결해도 문제없이 작동합니다.

// 키보드 라이브러리를 사용한다
#include <Keyboard.h>

// 사용하는 핀번호를 지정한다
#define PIN_ROW_1 19
#define PIN_ROW_2 18
#define PIN_ROW_3 15
#define PIN_ROW_4 14
#define PIN_ROW_5 16
#define PIN_COL_1 7
#define PIN_COL_2 6
#define PIN_COL_3 5
#define PIN_COL_4 4

// 사용할 배열의 크기를 지정한다. 5행 x 4열 = 20
#define MATRIX_SIZE 20

// PC로 전송할 키코드
const byte keycode[MATRIX_SIZE] = {219, 220, 221, 222,   // N / * -
                                   231, 232, 233,   0,   // 7 8 9
                                   228, 229, 230, 223,   // 4 5 6 +
                                   225, 226, 227,   0,   // 1 2 3
                                   234,   0, 235, 224};  // 0   . E

// 스위치 스캔 결과를 기록할 배열
bool bufferA[MATRIX_SIZE];
bool bufferB[MATRIX_SIZE];

// 어떤 배열에 이전/현재 결과가 들어있는지 지정한다
bool *prevBuffer = &bufferA[0];
bool *curBuffer = &bufferB[0];
bool *tempBuffer;

// 채터링 현상 방지용 지연시간을 지정한다
#define DEBOUNCE_DELAY 20

// 키별로 마지막으로 상태변화가 일어난 시간을 기록할 배열
unsigned long lastChange[MATRIX_SIZE];
unsigned long curMillis;


// 아두이노 초기설정
void setup() {
  // 스캔 결과를 기록할 배열을 초기화한다 (1: 대기상태, 0: 키 눌러짐)
  for (int i = 0; i < MATRIX_SIZE; i++) {
    bufferA[i] = 1;
    bufferB[i] = 1;
  }

  pinMode(PIN_ROW_1, OUTPUT);
  pinMode(PIN_ROW_2, OUTPUT);
  pinMode(PIN_ROW_3, OUTPUT);
  pinMode(PIN_ROW_4, OUTPUT);
  pinMode(PIN_ROW_5, OUTPUT);

  digitalWrite(PIN_ROW_1, HIGH);
  digitalWrite(PIN_ROW_2, HIGH);
  digitalWrite(PIN_ROW_3, HIGH);
  digitalWrite(PIN_ROW_4, HIGH);
  digitalWrite(PIN_ROW_5, HIGH);

  pinMode(PIN_COL_1, INPUT_PULLUP);
  pinMode(PIN_COL_2, INPUT_PULLUP);
  pinMode(PIN_COL_3, INPUT_PULLUP);
  pinMode(PIN_COL_4, INPUT_PULLUP);
}


// 아두이노 반복실행 코드
void loop() {
  // 스위치별로 입력상태를 확인한고 결과를 버퍼에 기록한다
  digitalWrite(PIN_ROW_1, LOW);
  curBuffer[0] = digitalRead(PIN_COL_1);
  curBuffer[1] = digitalRead(PIN_COL_2);
  curBuffer[2] = digitalRead(PIN_COL_3);
  curBuffer[3] = digitalRead(PIN_COL_4);
  digitalWrite(PIN_ROW_1, HIGH);
  digitalWrite(PIN_ROW_2, LOW);
  curBuffer[4] = digitalRead(PIN_COL_1);
  curBuffer[5] = digitalRead(PIN_COL_2);
  curBuffer[6] = digitalRead(PIN_COL_3);
  //curBuffer[7] = digitalRead(PIN_COL_4);
  digitalWrite(PIN_ROW_2, HIGH);
  digitalWrite(PIN_ROW_3, LOW);
  curBuffer[8] = digitalRead(PIN_COL_1);
  curBuffer[9] = digitalRead(PIN_COL_2);
  curBuffer[10] = digitalRead(PIN_COL_3);
  curBuffer[11] = digitalRead(PIN_COL_4);
  digitalWrite(PIN_ROW_3, HIGH);
  digitalWrite(PIN_ROW_4, LOW);
  curBuffer[12] = digitalRead(PIN_COL_1);
  curBuffer[13] = digitalRead(PIN_COL_2);
  curBuffer[14] = digitalRead(PIN_COL_3);
  //curBuffer[15] = digitalRead(PIN_COL_4);
  digitalWrite(PIN_ROW_4, HIGH);
  digitalWrite(PIN_ROW_5, LOW);
  curBuffer[16] = digitalRead(PIN_COL_1);
  //curBuffer[17] = digitalRead(PIN_COL_2);
  curBuffer[18] = digitalRead(PIN_COL_3);
  curBuffer[19] = digitalRead(PIN_COL_4);
  digitalWrite(PIN_ROW_5, HIGH);

  // 현재 스캔이 완료된 시간을 기록한다
  curMillis = millis();
  
  // 이전/현재 스캔 결과를 비교하여 모든 키를 처리한다
  for (int i = 0; i < MATRIX_SIZE; i++) {
    // 키입력 상태의 변화가 없을 때는 다음 키로 넘어간다
    if (prevBuffer[i] == curBuffer[i]) continue;

    // 너무 짧은 시간안에 상태가 변했다면 채터링으로 간주하고 무시한다
    if (curMillis - lastChange[i] < DEBOUNCE_DELAY) {
      curBuffer[i] = prevBuffer[i];
      continue;
    } else
      lastChange[i] = curMillis;
    
    // 문제가 없다면 해당 키의 마지막 상태변화 시간을 갱신한다
    lastChange[i] = curMillis;
    
    // 키를 변화방향을 확인하고 PC로 적절한 신호를 전송한다
    if (curBuffer[i] == 0)
      Keyboard.press(keycode[i]);
    else
      Keyboard.release(keycode[i]);
  }
  
  // 이전 스캔 결과와 현재 스캔 결과를 저장하는 배열을 서로 바꿔준다
  tempBuffer = prevBuffer;
  prevBuffer = curBuffer;
  curBuffer = tempBuffer;
}

 

9. 마치며

이것으로 커스텀 키보드 제작과정에 대해서 간단하게 알아보았습니다. 복잡한 기능이 들어간 키보드도 전체적인 흐름은 변하지 않으니 이정도만 기억하시면 충분히 만들 수 있을 거라고 생각합니다. 다음 글부터는 직접 키보드 제작에 들어가면서 보다 자세한 내용을 담을 예정입니다. 그럼 다음 글에서 뵙겠습니다.

+ Recent posts