20 min read

스플릿 키보드 만들기 프로젝트

스플릿 키보드 만들기 프로젝트

시작하게 된 계기

기계식 키보드에 관심을 가지기 시작한 건 아마, 대학교 4학년 무렵, 내 진로를 프로그래밍 쪽으로 변경해야겠다고 생각했을 무렵이었다. 전자과와 전산과 프로그래밍 수업들을 본격적으로 듣기 시작하면서, 자연스럽게 타이핑을 하는 시간이 많아졌고, 좋은 키보드에 대한 관심이 생겼다.

처음 구매했던 키보드는 레오폴드사의 갈축 키보드였다. 처음 사는 기계식 키보드였던 만큼 너무 시끄럽지도, 너무 재미없지도 않은, 무난한 갈축을 구매했고 오랜 기간 만족하며 잘 사용했다. 첫 번째 키보드는 기숙사에서 사용하고, 대학원을 다니며 연구실에서 사용할 키보드가 필요해지면서 새로운 키보드를 알아봤다. 이때 구매한 키보드가 한성 무접점 키보드였다. 이때도 온갖 유튜브 영상들을 찾아다니며 어떤 제품이 나에게 잘 맞을지 고민하고 구매했다. 이 무접점 키보드는 아직도 집에서 메인 키보드로 사용할 만큼 만족도가 높았다.

이때까지만 해도, 적축, 청축, 갈축, 무접점 외에는 잘 몰랐고 키보드 그 자체에 대해서는 관심이 높지 않았는데, 키보드에 대한 관심이 크게 증가하게 된 계기가 있었다. 바로 아래 영상이었다.

누군가 아두이노로 한국인을 위한 인체공학 split 키보드를 만들어 올렸다.

어떤 계기로 알게 되었는지는 모르겠지만, 이 영상을 보고 너무 신기했다. 전혀 생각해보지 못한 영역이었는데, 키보드를 개인이 취미로 만들 수 있다니!
하지만 늘 그렇듯, '세상에는 별 사람들이 다 있구나' 정도의 생각에 그쳤다. 그렇게 잊고 있던 중, 키보드에 대한 관심이 다시 생기게 되는 결정적인 계기가 있었다.

4년 넘게 다니던 회사에서 여러 가지 일들을 겪은 후 퇴사를 하면서 너무나 시원섭섭하면서도, 나 혼자 무언가를 만들어보거나 뭔가를 이뤄보고 싶다는 욕구가 샘솟았다. 대학원 입학 이후, 처음으로 월급을 받지 않는 대신 온전한 하루를 가지게 된 시점에서, 예전에 관심 가졌던 키보드를 만들어보겠다는 생각을 했고, 무언가를 뚝딱뚝딱 만들며 PCB 만드는 것도, 3D 프린팅 하는 것도 배워보겠다고 다짐했다.

그렇게 일을 벌였다.

프로젝트 준비: 사전 조사

키보드의 원리

제일 처음은 키보드의 원리를 이해하는 것부터 시작했다. 레고 조립하듯 따라만 하면 될 정도의 친절한 리소스들이 워낙 많았지만, 그렇게 하다 보면 어떤 지점에서 문제가 생겨도 디버깅이 불가할 것 같아서 원리부터 이해하기로 했다.

다행히 생각보다 친절하게 설명된 블로그 글들이 많았다. 키보드가 동작하는 원리는 기본적으로 그물처럼 연결된 grid 에서 행 또는 열마다 일정한 간격으로 신호를 쏴주고 스위치가 눌릴 때 마다 해당하는 위치에서 전류가 흐르면 어떤 키가 인식되었는지 계산하는 원리이다. 이 과정에 다이오드가 필요한 이유는 동시에 여러 키를 눌렀을 때 발생하는 고스팅 현상을 방지하기 위해서라고 한다.

[일반] 풀와이어링 키보드 제작 가이드 1. 키보드 매트릭스 원리 이해하기

위 글을 비롯해서 잘 설명된 글들이 많아서 조금만 읽어보면 이해될 정도로 어렵지 않다.

어떤 키보드를 만들 것인가?

내가 딱히 엄청 까다로운 취향을 가졌거나 시중에 있는 것들이 불편해서 완전히 새로운 키보드를 만들고자 했던 것은 아니었는데, 이 레퍼런스를 발견하고 이 레이아웃을 기준으로 만들어보기로 했다.

이미지 출처: https://github.com/gyuha/my-keyboard

이 레이아웃을 선택한 이유는 명확했다:

  1. 스플릿 키보드를 만들고 싶었다: 손목과 어깨에 무리가 덜 가는 자세. (+특이하고 있어보이는 키보드…)
  2. 양쪽에 'b' 키가 필요했다: 한국인은 'ㅠ'를 오른손으로 타이핑하지만 영어 'b'는 왼손으로 친다. 대부분의 스플릿 키보드에는 'b' 키가 왼쪽에만 있어서, 오른쪽에도 'b' 키가 있는 스플릿 키보드를 만들고 싶었다.
  3. 적응 가능한 레이아웃: 대부분의 스플릿 키보드들은 다소 괴랄(?)한 레이아웃을 가지고 있는데, 적응할 자신이 없었다. 그냥 깔끔한 기존 모양의 키보드를 사용하고 싶었다.

레이아웃은 https://www.keyboard-layout-editor.com/ 이 사이트에서 간단하게 만들수 있다.

PCB? 핸드 와이어링?

내가 처음 봤던 유튜브 영상은 모든 키를 전선으로 연결한 핸드 와이어링(hand-wiring) 방식의 키보드였다. 그런데 이왕이면 PCB 만드는 것도 배워보고 싶었어서 그냥 PCB로 해야겠다고 생각했다.

(이미지 출처: https://github.com/mastery6/wingB_Korean-Split-keyboard)

이런식으로 만드는게 hand-wiring 방식이고, 보다시피 납땜을 엄청 많이 해야한다.

케이스 만들기

케이스를 만드는 방식도 여러 가지가 있었다.

  • 첫 번째는 3D 모델링을 한 후 출력하는 방식이고,
  • 두 번째는 아크릴을 뽑아서 쌓아올리는 방식이었다.

아크릴 적층 방식이 있다는 건 나중에 알게 되었고, 기존 레퍼런스 repository 에 있던 3d modeling 파일을 3D 프린터로 출력해봤다. 그런데 내가 요령이 없어서 그런지 필라멘트 층이 그대로 다 보이고 생각보다 퀄리티가 아쉬워서 아크릴 적층 방식으로 해봐야겠다고 생각했다.

(3d printing 도 잘만든 사람들꺼는 양산품처럼 놀랍도록 정교하던데 그 차이가 뭔지 잘 모르겠다)

이 때 찾아본 훌륭한 아크릴 적층 방식 케이스의 레퍼런스들은 다음과 같다.


PCB 설계 및 제작

물리과를 나와서 대학원을 전자공학과로 졸업했지만 회로 관련해서는 수업을 거의 전혀 듣지 않았기 때문에 거의 아무것도 모르는 상태에서 PCB를 만드는 게 가능할까 싶었다. 그래도 ChatGPT 가 있으니 도전해 보기로 했다. 사용한 툴은 KiCad 인데, KiCad는 오픈소스 PCB 설계 툴로 무료로 사용할 수 있다. 유튜브 채널 회로와코딩 (전 처음코딩) 님의 PCB 강의 를 참고하면서 기본 사용법을 익혔다.

설계 과정

기본 레이아웃을 만드는 데는 아래의 github repo 를 활용했다. 이 라이브러리를 사용하면 위에서 생성한 layout 을 기반으로 pcb 초안을 생성할 수 있다.

생성된 pcb 레이아웃이 완벽하지는 않아서 직접 회로를 연결해야하긴 하지만, 키보드 스위치 배치와 기본적인 간격 등이 잘 맞는 편이라 반복적인 작업을 상당히 줄일 수 있었다.

https://kbfirmware.com/ 이 사이트에 위에서 생성한 레이아웃 json 파일을 입력하면 wiring 을 수정할 수 있는데, 아래와 같이 수정하였다. 규칙이 따로 있는 건 아니고 적절하게 배선이 잘 될 수 있게 수정하면 된다. 그런 다음 이 배선대로 pcb 상에서 wiring 을 해주면 된다. 아두이노에서 어떤 pin 에 연결하는지는 레퍼런스 repo 를 참고하여 만들었다.

Pro-micro 아두이노의 스키매틱(schematic) 심볼이 없어서 한참 동안 외국 사이트들을 뒤져서 찾아냈고, 내가 주문한 스테레오 커넥터 부품의 스키매틱 심볼도 없어서 이것도 간단하게 그려봤다.

아두이노 프로 마이크로 스키메틱 심볼

PCB를 다 만들고 회로 연결 여부를 검사하는 DRC(Design Rule Check)를 돌려서 제대로 됐는지 확인했다. 큰 문제가 없어 보였고, 그렇게 아래와 같은 PCB 를 완성했다.

PCB 와 관련한 레퍼런스들

주문과 제작

JLCPCB라는 중국 사이트 (https://jlcpcb.com/) 에 들어가서 주문을 했다. 취미로 PCB 를 만들어보는 사람들이 가장 많이 사용하는 사이트인 것 같은데, 어떻게 주문을 하는지는 유튜브에 찾아보면 아주 상세하게 나온다.

이 사이트의 가장 큰 장점은 다이오드 같은 부속을 포함해서 납땜까지 제공해 주는 옵션이 있다는 것이었다. 정확한 이름은 기억이 안나지만 ‘SMT Assembly’ 같은 옵션인데, 원래는 다이오드까지 다 따로 구매했었는데, 이걸 다 납땜하려고 했으면 납땜해야 하는 양이 거의 2배가 되는 셈이라 ChatGPT에게 물어가며 해당 옵션을 활용했다. 다이오드는 극성이 있다보니 이게 너무 헷갈려서 몇 차례 확인하고 주문했던 기억이 난다. 최소 주문 갯수가 5장이라서 왼쪽 오른쪽 각각 5장씩 주문하였는데 대략 10만원 안쪽으로 나왔다.

놀랍게도 1주일 안에 배송이 완료됐다. 오픈소스 라이브러리로 PCB 베이스라인을 그려서 받아보긴 했지만, 내가 PCB를 그려서 받아보다니!
물론 아직 동작하는 건 확인하지 못한 상태였다. 솔직히 한 40% 정도의 확률로 안 동작할 것 같다는 생각이 들었다.

나중에 알게 된 사실인데, 오른쪽 파트는 스테빌라이저(stabilizer) 구멍을 뚫지 않았다는 것과, 스테레오 커넥터 구멍을 빠뜨렸다는 것도 알게 됐다. 예상했지만 역시나 군데 군데 실수가 있었다. 다시 주문하기에는 지출도 꽤 크고, 연습삼아 만들어보자는 생각이 커서 재주문을 하지는 않았다.

도착한 PCB. 내가 만든 것 치고는 꽤나 그럴싸했다.

여기까지가 2024년 8월경 진행했던 내용이었다.

PCB가 도착한 이후 이걸 테스트해 볼 엄두가 안 나서 집 어딘가에 잘 쌓아두고 있었고, 새로운 회사를 결정하기 위해 여기저기 인터뷰를 보면서 자연스럽게 머릿속에서 잊혀져 버렸다.

그러다 2025년 10월, 긴 추석 연휴를 활용해서 마무리하지 못한 이 키보드 만들기 프로젝트를 다시 마무리해 보자는 생각이 들어서 박스를 꺼냈다.


조립 및 하드웨어 테스트

아두이노 납땜

먼저 Pro-micro 아두이노를 PCB에 납땜했다. 아두이노는 대학생 때 아프리카에서 봉사활동하면서 처음 써봤는데, 그때의 경험이 또 도움이 됐다. 핀 배치를 확인하고 조심스럽게 납땜을 진행했다. PCB에 아두이노 납땜을 다 하고, 아두이노와 가장 가깝게 연결된 키 하나를 납땜했다. 그리고 잘 입력이 되는지 확인해 봤는데, 첫 시도만에 키가 잘 입력되는 걸 보고 신나서 모든 키를 납땜했다.

모든 키를 납땜한 후 ChatGPT를 이용해서 모든 키에 대해서도 확인할 수 있게 아두이노 스크립트를 작성했는데, 아까 입력이 잘 되던 키를 제외하고는 전혀 반응이 없었다...

순간 절망했지만, 원인을 찾다가 테스트 코드가 잘못된 것을 깨달으며 안도하고, 코드를 제대로 고치니 모든 키가 다 잘 동작했다. 왼쪽, 오른쪽 모두 키가 잘 동작하는 것을 확인했다.

사용했던 테스트 아두이노 코드

// Col pins: 4,5,6,7,8,9,A3,A2
// Row pins: A0,15,14,16,10
const int colPins[] = {4, 5, 6, 7, 8, 9, A3, A2, A1};   // 입력(PULLUP)
const int rowPins[] = {A0, 15, 14, 16, 10};         // 출력(LOW로 활성화)
const int NUM_COLS = sizeof(colPins)/sizeof(colPins[0]);
const int NUM_ROWS = sizeof(rowPins)/sizeof(rowPins[0]);
const int LED_PIN  = 17; // TX LED

bool keyState[5][9];  // R×C 이전 상태 저장

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }
  Serial.println("Matrix scan start (Row=OUT, Col=IN_PULLUP)");

  // Row = OUTPUT, 기본 HIGH
  for (int r=0; r<NUM_ROWS; r++) {
    pinMode(rowPins[r], OUTPUT);
    digitalWrite(rowPins[r], HIGH);
  }
  // Col = INPUT_PULLUP
  for (int c=0; c<NUM_COLS; c++) {
    pinMode(colPins[c], INPUT_PULLUP);
  }
  pinMode(LED_PIN, OUTPUT);
  memset(keyState, 0, sizeof(keyState));
}

void loop() {
  bool anyPressed = false;

  for (int r=0; r<NUM_ROWS; r++) {
    digitalWrite(rowPins[r], LOW);
    delayMicroseconds(50);  // 정착시간

    for (int c=0; c<NUM_COLS; c++) {
      bool pressed = (digitalRead(colPins[c]) == LOW);
      if (pressed != keyState[r][c]) {
        keyState[r][c] = pressed;
        Serial.print(pressed ? "DOWN " : "UP   ");
        Serial.print("R"); Serial.print(r);
        Serial.print(" C"); Serial.println(c);
      }
      anyPressed |= pressed;
    }
    // Row 비활성화
    digitalWrite(rowPins[r], HIGH);
  }

  digitalWrite(LED_PIN, anyPressed ? HIGH : LOW);
  delay(5);
}

펌웨어 개발 (QMK)

QMK란?

QMK(Quantum Mechanical Keyboard)는 커스텀 키보드를 위한 오픈소스 펌웨어다. 키 매핑, 레이어, 매크로 등 다양한 기능을 지원하고, 커스텀 키보드 커뮤니티에서 사실상 표준으로 사용되고 있다. 많은 사람들이 사용하고 레퍼런스가 풍부한 편이라 선택했다.

문제는 라이브러리가 업데이트된 탓인지 기존에 사람들이 사용하던 방식과는 조금 차이가 있었다는 것이다. ChatGPT도 이상한 짓들을 하며 헤매고 있을 때, 역시 정답은 QMK 공식 문서에 있었다.

새로운 키보드를 QMK에 추가하려면 아래의 커맨드를 사용하면 된다.

qmk new-keyboard

그리고 왼쪽과 오른쪽을 구분해 주도록 설정했다. (split keyboard 일 경우)

# 왼쪽 연결
qmk flash -kb lees_split -km default -bl avrdude-split-left

# 왼쪽 제거, 오른쪽 연결
qmk flash -kb lees_split -km default -bl avrdude-split-right

ChatGPT와 함께 협동해 가며 여러 가지 설정을 마치고, 두 개의 키보드를 각각 USB로 연결했더니 너무 잘 동작했다. 딜레이도 거의 없었다. 타이핑해 보니 반응이 즉각적이었고, 각 키보드가 독립적으로 완벽하게 동작했다.

현재 직면한 문제

그런데 문제가 생겼다. 왼쪽과 오른쪽 디바이스가 별도의 키보드로 인식되어서 왼쪽 Shift를 누르고 오른쪽 키보드를 치거나 반대로 할 때 먹지 않았다. 두 개의 독립적인 키보드로 인식하기 때문이었다.

이 문제를 해결하려면 TRRS(Tip-Ring-Ring-Sleeve) 커넥터로 두 키보드를 연결하여 하나를 Master, 하나를 Slave로 인식하게 해야 한다. 원인을 모르겠지만 이 TRRS 커넥터를 연결하면 입력이 되지 않았다. 여러 가지를 시도해 봤다:

  • QMK 설정에서 split keyboard 옵션 확인
  • TRRS 케이블의 연결 상태 확인
  • 펌웨어 재빌드 및 재업로드

하지만 아직 원인을 찾지 못했다. 내가 이해한게 맞다면, TRRS 커넥터의 핀 연결은 제대로 된것 같은데, 펌웨어 설정이 제대로 되지 않은 것 같다. 가까운 곳에 키보드 고수가 있다면 도움을 청하고 싶은데, 쉽지는 않을것 같다.

현재 상황과 소회

긴 추석 연휴 중 2-3일 정도를 이걸 붙잡고 납땜하고, 코드 짜고, 디버깅하고, 다시 시도하는 과정의 반복하니 피곤하기도 했지만, 무언가 생산적인 일을 했다는 보람과 몰입의 순간이 주는 즐거움도 분명 있는것 같다.

사실 완성도 높은 키보드를 만들기 위해서 남아있는 단계는:

  1. TRRS 문제 해결
  2. PCB 마이너 수정 (TRRS 스키매틱 수정 및 스테빌라이저 구멍) 후 재주문
  3. CAD로 케이스 디자인 및 조립

정도가 남았는데, 이건 언제 완성할 수 있을지 모르겠다. 케이스 만들어 보려고 기초적인 CAD 사용법도 유튜브로 배워봤는데, 당장은 해보기 어렵지 않을까 싶다.

그리고 아이러니하게도, 처음 이 프로젝트를 시작할 때는 내가 괴랄한 레이아웃의 스플릿 키보드를 사용하지 않을 것이라고 생각하고 b 키가 포함된, 일반적인 키보드 레이아웃과 가까운 키보드를 만들고 싶었던 것인데, 그 사이에 나는 Keyboardio 의 Model 100 이라는 제품을 당근에서 꽤 저렴하게 구입하게 되었고, 어느덧 적응도 하게 되어서 이 프로젝트가 완성되어도 실 사용은 완성도 높은 이 제품을 사용하게 될것 같다.
(물론 완성하면 엄청 내가 만든 키보드라는 점에서 애착은 생기겠지만)

우연히 당근에서 보고 충동구매 해버린 키보드. 솔직히 디자인은 너무 예쁘다고 생각한다.

이 프로젝트를 완벽하게 완성하게 되는 시점이 언제일지는 모르겠지만, 이 정도라면 애초에 생각했던 목표는 어느 정도 이룬 것 같다.

  1. 전혀 모르던 키보드를 공부해 가며 원리를 이해하고, 직접 만들어보기
  2. 그 과정에서 PCB를 만드는 방법, 3D 모델링, CAD의 아주 아주 기초적인 사용방법을 배움: KiCad로 회로도를 그리고, 실제로 주문해서 받아보는 경험을 했다.
  3. 이 과정을 통해 다시 한 번 의지만 있다면 뭐든 배울 수 있는 세상이라는 것을 확인: ChatGPT, 오픈소스 라이브러리, 유튜브, 블로그... 배우려는 의지와 시간만 있다면 불가능한게 별로 없는 세상에 살고 있는 것 같다.

완벽한 완성보다 과정에서의 배움이 더 중요했던 프로젝트였다. 처음 해보는 것들 투성이었지만, 퇴사 후 "나 혼자 무언가를 만들어보고 싶다"는 욕구를 충족할 수 있었다. 열정도 시간도 많은 백수였기에 가능했던것 같고, 언젠가 멋진 케이스까지 만들고 이 글에 업데이트를 할 수 있는 날이 오길.

그 외 레퍼런스들

부품명 수량 링크 가격 구매완료
아두이노 프로 마이크로
Arduino ATmega32U4 2 연결
래핑 와이어 (전선) 1 연결
스테레오 커넥터 / 3.5mm / FEMALE 2 연결 180
3.5mm aux 케이블
체리 스테빌 라이저
Kailh BOX 코코넛 라떼 크림 사일런트 스위치 80 알리
다이오드 80 연결 15
범폰 스티커 쿠팡
Gateron Hot-swappable PCB Socket 90 연결 14368