0. 재료
1. 모양 구상
2. 키캡 구입
3. 디자인
4. 키 배열 ← 여기까지 1단계 : http://www.kbdmania.net/xe/tipandtech/8635141
5. 조립 & 납땜 ← 여기까지 2단계 : http://www.kbdmania.net/xe/tipandtech/8639304
6. 아두이노 프로그래밍 ← 여기까지 3단계

마지막으로 소프트웨어를 만들어 넣어주는 것으로 키보드에 생명을 창조시키겠습니다. 음화화


---


개념적으로 볼 때 첫째 시간에는 우선 키보드 모양을 정한 뒤 키를 약간개의 그룹으로 묶는 일을 했습니다.

1.png




둘째 시간에는 앞서 정한 묶음을 실제로 10k옴 저항을 이용해서 줄줄이 엮었습니다. 그림으로 보자면 납땜 하다보니 좌우 반전되어 이런 식이 됐겠죠.


2.png



그럼 이번 시간에는 아래 그림처럼 만들 필요가 있습니다.


3.png



첫째 시간에서 그린 그림에 둘째 시간에 엮은 순서를 적어둔 상태지요. 이 순서를 적어두면 프로그래밍이 훨씬 쉬워지니 메모해두도록 합시다.


---


지난 시간의 마지막 단계는 "시리얼 모니터"를 이용해서 1023 1023 1023 하는 숫자들이 막 들어오고 키를 누르면 어떤 숫자가 1023보다 낮아지고 그랬었는데요. 예를 들어서 제 경우에는 키보드에 달려있는 실제키 A키를 누르면


Untitled-1.jpg



이렇게 A2가 210으로 낮아지는걸 볼 수 있습니다. 이거는 물론 우연히 제 경우에 A키가 아날로그2번 묶음에 붙어있었고, 두 번째 키에 붙어있어서 210이 들어온것이니 여러분들이 A키를 누를 때와 숫자의 위치나 값은 다를 수 있습니다. 하지만 이런 식으로 특정 키를 누르면 특정 항목의 값이 변하게 됩니다.

그러면 이거를 프로그래밍 하기 좋게 패턴으로 만들어두도록 합시다.

오늘 한다고 했던 세번째 그림에서 보시면 제 경우 A키는 초록색 키(A2)의 2번째에 있습니다. 그러면 실제 키보드의 캡스락 키를 누르면 A2의 1번 값이 들어오리라는걸 알 수 있습니다. A는 2번째, 탭은 3번째, Q는 4번째, 1은 5번째 하는 식이겠죠.

이걸 순서대로 눌러서 A2값이 어떻게 변하는지 확인해보겠습니다.

1번 : 15
2번 : 210
3번 : 340
4번 : 433
5번 : 504
6번 : 559
7번 : 603
8번 : 640
9번 : 670
10번 : 697
11번 : 720
12번 : 739
안누름 : 1020

+- 2 정도 오르락 내리락 하는데 대충 이런 값이 나온다는 것을 발견했습니다. 이건 물론 제 경우입니다. 지난시간 10k옴인줄 알고 쓴 저항이 사실 9.1k옴이어서 아마 여러분 보다 값이 조금씩 높을 것 같습니다. 아두이노 보드나 여러가지 요인에 따라서 조금씩 다를테니 직접 눌러보셔야합니다.

이번엔 다른 키들이 달려있는 A0쪽을 한 번 재어보겠습니다. 이쪽도 역시 +- 2정도 차이는 있어도 똑같습니다. A0 A1 A2 A9 A10 전부 똑같네요. 헤헤... 저항을 한 가지 종류만 써서 문제 없이 다 달았다면 이렇게 핀 관계 없이 같은 단계를 갖는 값이 받아집니다. 설명할 수 없는 요인에 의해서 아날로그핀마다 값이 다르게 찍힐 수 있는데 각 단계만 구분된다면 문제는 없습니다. 하지만 A0에 붙인 스위치를 눌렀는데 A0이랑 같이 A1도 변한다든지 한다면 땜질을 잘못 하신거니 해당 부분 땜을 다시 살펴보시기 바랍니다.

참고로, 사용한 저항은 10k옴 한 종류인데 저항을 안달은 15에서 -> 하나 달은 210에는 195만큼 값이 차이나는데 점점 달아나갈 수록 값의 차이가 줄어들어서 11개 일땐 720이지만 -> 12개일땐 739로 19밖에 차이가 안나지요. 이래서 '아날로그 핀' 하나에 키를 13~14개밖에 달 수가 없습니다. 그 이상 달면 값 차이가 별로 나지 않아서 키를 구분할 수가 없으니까요. 굳이 키를 더 달고 싶으시면 처음에는 10k옴보다 값이 낮은 3k옴 정도를 사용하기 시작해서 뒤에는 10k옴보다 값이 높은 30k옴 정도를 사용하면 값 차이를 구분할 수 있으니 키를 몇 개 더 연결할 수 있겠습니다만 그 밖의 여러 가지 문제로 인해서 별로 추천하지는 않습니다.

자 아무튼 그럼 이제 각 키들 값도 알았으니 프로그래밍 하는 일만 남았네요. 아무래도 키보드 매니아에는 코딩 하시는 분들이 많이 계실 것 같아서 전혀 배운적이 없는 제가 팁이랍시고 적는게 좀 부끄러워지는데 뭐 그래도...


---


우선 아두이노는 아래와 같은 방식으로 동작합니다.

1. 변수 선언 부분
   ▷ 시킬게 없으면 생략 가능.
2. 최초 전원 인가시 1회만 동작하는 부분 : void setup() { }
   ▶ 시킬게 없어도 생략하면 안됨. 틀은 놔둬야됨.
3. 이후 무한히 반복할 부분 : void loop() { }
   ▶ 시킬게 없어도 생략하면 안됨. 틀은 놔둬야됨.

예를 들어서...

int WAIT = 10;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, 1);
  delay(WAIT);
  digitalWrite(13, 0);
  delay(WAIT);
}

라고 프로그램을 짰다고 치면

int WAIT = 100; // "WAIT" 라는 이름의 변수(=임시로 값을 기억시켜둘 공간)를 선언

void setup() { // 전원 인가시 최초 1회만 동작할 부분
  pinMode(13, OUTPUT); // 13번 핀을 출력 핀으로 사용한다고 선언
} // 전원 인가시 최초 1회만 동작할 부분 끝

void loop() { // 이후 무한히 반복될 부분
  digitalWrite(13, 1); // 13번 핀에 디지털신호 1 = 켜짐을 전송
  delay(WAIT); // "WAIT" 라는 이름의 변수에 적혀진 숫자만큼 대기
  digitalWrite(13, 0); // 13번 핀에 디지털신호 0 = 꺼짐을 전송
  delay(WAIT); // "WAIT" 라는 이름의 변수에 적혀진 숫자만큼 대기
} // 무한히 반복될 부분 끝

와 같이 되어, 100ms에 한 번씩 13번 핀에 5볼트가 들어갔다 안들어갔다 반복하는 아두이노가 만들어집니다. 13번 핀에 LED의 +극 다리를 끼우고, -핀에 LED의 -극 다리를 끼우면 깜빡이는 LED가 만들어지는 것입니다.

키보드를 만들 때에도 똑같습니다. 실제로 해보도록 하겠습니다. 앞서 봤던 세번째 키보드 그림을 다시 보겠습니다.


3.png




보라색 A0핀을 할 생각입니다. 저는 지금 z - w - esc - 2 - 4 - 6 - y - 8 - i - 0 - 윗방향키 - b 순서로 저항을 붙여놨네요.

그리고 앞서 측정해둔 스위치 단계별 값도...


1번 : 15
2번 : 210
3번 : 340
4번 : 433
5번 : 504
6번 : 559
7번 : 603
8번 : 640
9번 : 670
10번 : 697
11번 : 720
12번 : 739
안누름 : 1020

이제 코딩을 짜면...

void setup() {
  pinMode(A0, INPUT_PULLUP);
}

void loop() {
  if (analogRead(A0) < 20) {
    Keyboard.press('z');
  }
  else if (analogRead(A0) < 220) {
    Keyboard.press('w');
  }
  else if (analogRead(A0) < 350) {
    Keyboard.press(KEY_ESC);
  }
  else if (analogRead(A0) < 450) {
    Keyboard.press('2');
  }
  else if (analogRead(A0) < 520) {
    Keyboard.press('4');
  }
  else if (analogRead(A0) < 570) {
    Keyboard.press('6');
  }
  else if (analogRead(A0) < 620) {
    Keyboard.press('y');
  }
  else if (analogRead(A0) < 650) {
    Keyboard.press('8');
  }
  else if (analogRead(A0) < 680) {
    Keyboard.press('i');
  }
  else if (analogRead(A0) < 710) {
    Keyboard.press('0');
  }
  else if (analogRead(A0) < 730) {
    Keyboard.press(KEY_UP_ARROW);
  }
  else if (analogRead(A0) < 750) {
    Keyboard.press('b');
  }
  else {
    Keyboard.release('z');
    Keyboard.release('w');
    Keyboard.release(KEY_ESC);
    Keyboard.release('2');
    Keyboard.release('4');
    Keyboard.release('6');
    Keyboard.release('y');
    Keyboard.release('8');
    Keyboard.release('i');
    Keyboard.release('0');
    Keyboard.release(KEY_UP_ARROW);
    Keyboard.release('b');
  }
}

짠! 됐습니다. 이렇게 작성하여 아두이노에 업로드 시킵니다. 키 12개를 처리했는데 생각보다 간단하죠? 주석을 달아서 다시 보겠습니다.

void setup() { // 초기 1회 부분
  pinMode(A0, INPUT_PULLUP); // A0핀을 입력 핀으로 선언
} // 초기 1회 부분 끝

void loop() { // 무한 반복 부분
  if (analogRead(A0) < 20) { // 만약에 A0핀의 아날로그값이 20 이하라면
    Keyboard.press('z'); // 'z' 키를 누름
  }
  else if (analogRead(A0) < 220) { // 20 이하가 아니었다면, 혹시 220 이하라면
    Keyboard.press('w'); // 'w' 키를 누름
  }
  else if (analogRead(A0) < 350) { // 220 이하도 아니었다면, 혹시 350 이하라면
    Keyboard.press(KEY_ESC); // KEY_ESC 키를 누름
  }
  else if (analogRead(A0) < 450) { // 350 이하도 아니었다면, 혹시 450 이하라면
    Keyboard.press('2'); // '2' 키를 누름
  }
  else if (analogRead(A0) < 520) { // 450 이하도 아니었다면, 혹시 520 이하라면
    Keyboard.press('4'); // '4' 키를 누름
  }
  else if (analogRead(A0) < 570) { // 520 이하도 아니었다면, 혹시 570 이하라면
    Keyboard.press('6'); // '6' 키를 누름
  }
  else if (analogRead(A0) < 620) { // 570 이하도 아니었다면, 혹시 620 이하라면
    Keyboard.press('y'); // 'y' 키를 누름
  }
  else if (analogRead(A0) < 650) { // 620 이하도 아니었다면, 혹시 650 이하라면
    Keyboard.press('8'); // '8' 키를 누름
  }
  else if (analogRead(A0) < 680) { // 650 이하도 아니었다면, 혹시 680 이하라면
    Keyboard.press('i'); // 'i' 키를 누름
  }
  else if (analogRead(A0) < 710) { // 680 이하도 아니었다면, 혹시 710 이하라면
    Keyboard.press('0'); // '0' 키를 누름
  }
  else if (analogRead(A0) < 730) { // 710 이하도 아니었다면, 혹시 730 이하라면
    Keyboard.press(KEY_UP_ARROW); // KEY_UP_ARROW 키를 누름
  }
  else if (analogRead(A0) < 750) { // 730 이하도 아니었다면, 혹시 750 이하라면
    Keyboard.press('b'); // 'b' 키를 누름
  }
  else { // 750 이하 조차 아니라면
    Keyboard.release('z'); // 'z' 키를 뗌
    Keyboard.release('w'); // 'w' 키를 뗌
    Keyboard.release(KEY_ESC); // KEY_ESC 키를 뗌
    Keyboard.release('2'); // '2' 키를 뗌
    Keyboard.release('4'); // '4' 키를 뗌
    Keyboard.release('6'); // '6' 키를 뗌
    Keyboard.release('y'); // 'y' 키를 뗌
    Keyboard.release('8'); // '8' 키를 뗌
    Keyboard.release('i'); // 'i' 키를 뗌
    Keyboard.release('0'); // '0' 키를 뗌
    Keyboard.release(KEY_UP_ARROW); // KEY_UP_ARROW 키를 뗌
    Keyboard.release('b'); // 'b' 키를 뗌
  }
} // 무한 반복 부분 끝

즉, 예를 들어서 실제 키보드에 A0 핀의 일곱 번째에 연결된 키인 Y 키를 누르면 아까 시리얼 모니터로 봤다시피 A0값이 603 +- 약간의 오차가 뜹니다. 그러면 analogRead(A0) 를 통해서 A0값을 읽었을 때 20 이하인가? 아니오 -> 220 이하인가? -> 아니오 ... 해서 쭉 훑다가 570 이하인가? -> 아니오 -> 620 이하인가? -> 예! 하는 순간이 발생합니다. 그러면 Keyboard.press('y'); 가 'y' 문자를 컴퓨터로 전송해서 y키를 눌렀음(누른겁니다. 눌렀다 뗀게 아니라 누르고 있는 중)을 알리게 됩니다.

이때에 620 이하인가? 에서 답변 예!가 발생했으니 그 이후 "else" 로 시작하는 질문들은 체크하지 않고 건너뛰게 됩니다. 그럼 다시 무한 반복 부분으로 올라와서 analogRead(A0) 을 하겠죠. 아직 손가락이 키를 떼지 않았으면 또다시 620 이하인가? 에서 예! 하게 되고 'y'가 아직 눌려있다고 알려줍니다.

그러다가 손가락을 떼면 A0값은 1020 정도로 회복이 되겠죠. 그럼 620 이하인가? -> 아니오 -> 650 이하인가? -> 아니오 ... 해서 뒷부분을 마저 읽게 됩니다. 750 이하인가? -> 아니오 -> 그것조차 아니라면(else) 부분이 실행되겠지요. 여기 else에서는 A0으로 누를 수 있는 종류의 키들 전부를 손가락 뗐다고 컴퓨터에 전송합니다. 이러면서 손가락이 Y 키를 뗐다는걸 컴퓨터도 알게 됩니다.

평소 아무 키를 누르지 않은 상태에서라면 언제나 else 부분이 실행되겠구요.

A0은 다 했으니 A1도 합니다. 아날로그핀 다섯개(혹은 그 이상) + 디지털핀 네개(혹은 그 이상) 전부 자신의 상황에 맞게 복붙해서 써주면 되겠습니다.

void setup() {
  pinMode(A0, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A9, INPUT_PULLUP);
  pinMode(A10, INPUT_PULLUP);
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
}

void loop() {
  if (analogRead(A0) < 20) {
  }
  if (analogRead(A1) < 20) {
  }
  if (analogRead(A2) < 20) {
  }
  if (analogRead(A9) < 20) {
  }
  if (analogRead(A10) < 20) {
  }
  if (digitalRead(0) == 0) {
  }
  if (digitalRead(1) == 0) {
  }
  if (digitalRead(2) == 0) {
  }
  if (digitalRead(3) == 0) {
  }
}

지면 관계상 생략하여 Read 안쪽 내용은 생략합니다. 이런식으로 쭉 써주시면 됩니다. 컨트롤/알트/윈도우/쉬프트 이런 키들은 디지털 핀으로 하셨을텐데 디지털핀은 digitalRead 로 읽으시면 되고 값은 1 = 스위치 뗌, 0 = 스위치 누름 두가지 종류로 들어옵니다.

아참 그리고 아까 위에서 숫자나 문자는 '1', 'a' 하는 식으로 적었는데 그 외에 특수키들 - ESC키나 DELETE키나 CTRL, ALT 등등의 키들도 있지요. 이런 키들은 아두이노 자체에서 특별한 이름을 통해서 지원하거나 아니면 HID Spec에 정의된 키보드 Scancode를 전송하는 방법으로 입력할 수 있습니다.


Untitled-2.png



이건 제가 고생해서 찾아낸 표준 104키 스캔코드를 표준 104키 키보드에 그려넣은 그림입니다. 아두이노에 넣었을 때 올바르게 동작하는 값으로 되어있어서 일반적인 스캔코드와는 값이 약간 다릅니다. 좋은 자료에요 이거... 보시면 KEY_LEFT_CTRL, KEY_RIGHT_SHIFT 처럼 아두이노에서 지원하는 특별한 이름이 있는 키도 있고 206, 92 처럼 스캔코드값으로 된 키도 있습니다. 요거 보시고 넣으시면 되겠습니다.

이렇게 Read한 값에 Keyboard.press와 Keyboard.release를 하는 것으로 키보드가 완성됩니다! 저거 위에꺼 다 하시고 키캡 끼우면 끝입니다. 별거 없죠?
1.JPG

2.JPG

3.JPG

IMG_0021.jpg



---


그 외

진짜로 벌써 키보드 만들기는 다 끝났습니다. 나머지는 악세사리입니다.

1. 한영/한자나 !@#$^ 특수문자는?

한영은 KEY_RIGHT_ALT, 한자는 KEY_RIGHT_CTRL로 하시면 윈도우즈에서 한영/한자 기능이 별다른 설정 없이 잘 됩니다.

특수문자는 원래 SHIFT가 눌려졌다(Press)면 '1' '2' '3'이 ! @ #으로 저절로 바뀌어 들어가집니다. 스캔코드가 같거든요.

참고로 한글 역시 그냥 'a', 'b', 'c' 하시면 알아서 ㅁ ㅠ ㅊ가 잘 쳐집니다.


---


2. 반복입력은?

위에서는 Keyboard.press, Keyboard.release를 썼습니다. 누를때 눌렀다고하고 뗐을 때 뗐다고 하는건데 이렇게 해주면 운영체제가 알아서 잘 해줍니다. 키를 누르면 일정 시간 동안에는 반복입력을 피하려고 키가 한 번만 눌린 상태가 됐다가 일정시간 이후에는 일부러 꾹 눌렀구나~ 하고 글자를 다다다다 쳐주는거죠.

이거를 옛날 게임기 터보 버튼처럼 그냥 누르고 있으면 지연시간 없이 계속 반복시킬 수도 있는데요, Keyboard.write가 그 기능입니다. press와 release를 동시에 하는 기능입니다. 따라서 별도로 release 할 필요 없이 Keyboard.write('a'); 하면 그냥 a키가 팡 쳐집니다. 다만 실제로는 반복입력되는 속도가 너무 빨라서 타이핑에선 쓰기가 어려운 기능입니다. 키 한번 누르는 것으로 여러 글자나 여러 문장을 입력하게 하는 매크로로 만들 수도 있으니 검색해보시고 응용하실 수 있겠습니다.


---


3. FN키

노트북 키보드에 보통 달려있는 'fn' 키는, 추측하셨겠지만 컴퓨터와 통신하는 키가 아닙니다. 예를 들어서 fn + 1 했을때 F1 키가 눌러지게 하려면 컴퓨터에 FN과 1을 던져주면 컴퓨터가 합성해주는 방식이 아니라는거지요. 키보드에서 합성해서 F1을 컴퓨터로 던져주는겁니다.

이거는 예를 들어서 FN키가 디지털핀 0번에 물려져있고 '1'키가 디지털핀 1번에 물려져있다고 했을 때에

int fn = 0;

void setup() {
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(0) == 0) {
    fn = 1;
  }
  else {
    fn = 0;
  }
  if (digitalRead(1) == 0) {
    if (fn == 1) {
      Keyboard.press(KEY_F1);
    }
    else {
      Keyboard.press('1');
    }
  }
  else {
    Keyboard.release(KEY_F1);
    Keyboard.release('1');
  }
}

처럼 Keyboard.press를 쓰는게 아니라 'fn' 이라는 변수를 선언하고, 키가 눌렸을 때 그 값을 0이나 1로 만드는 것으로 키보드 내부에서만 입력했나 안했나를 정한 다음에 FN키와 합성시킬 키들 각각에 'fn' 이라는 변수가 0이라면~ 1이라면~ 으로 구분을 해서 '1'을 넘기거나 KEY_F1을 넘기거나 할 수 있습니다.


---


4. 넘락/캡스락 LED는?

LED 자체는 일단 필요하신 위치에 붙이시고 -극은 다른 모든 키들의 한쪽 다리가 붙어있는 것과 마찬가지로 -극에 붙이시고, +극은 아두이노의 디지털핀 아무데나에 갖다 붙이시구요... 예를 들어서 13번 핀에 붙였다 하면

digitalWrite(13, 0); // 꺼짐
digitalWrite(13, 1); // 켜짐

으로 제어할 수 있습니다. 아두이노는 아주 쩔기 때문에 빛의 밝기 조절도 가능한데요

analogWrite(13, 0); // 꺼짐
analogWrite(13, 255); // 켜짐

처럼 0~255 단계로 빛 밝기를 변화시킬 수 있습니다.

다만 주의하실 점으로 저항 없이 아두이노 핀에 LED를 바로 붙이면 5볼트가 들어가지기 때문에 LED가 녹습니다. 이럴때는 200~300옴 정도의 저항을 하나 붙이시거나 아니면

analogWrite(13, 128);

과 같이 빛 밝기를 128을 넘지 않게 쓰시면 되겠습니다.

근데 이거보다 더 중요한건 넘락과 캡스락이 켜졌는지 꺼졌는지 신호를 컴퓨터에서 받아오는 방법인데요... 이건 아두이노에서 기본으로 지원해주질 않는 기능입니다. !? 그래서 검색을 한참 해보니 외국인이 이 기능을 사용할 수 있게끔 해둔 패치가 있는데요~ 그 패치는 키보드매니아 자료실에서 아두이노로 검색해보시면 제가 올려둔게 있습니다.

해당 패치를 아두이노 1.0.2에 덮어씌우시면 LED 상태를 받아올 수 있는 명령어가 추가됩니다. 1.0.2에만 가능하기 때문에 그 이상 높은 버전의 아두이노에서는 사용하실 수 없습니다.

해당 패치를 덮어씌우신 다음 Keyboard.getLedStatus() 로 현재 LED 상태를 알 수 있는데요, 다꺼짐0 넘락1 캡스락만2 넘락캡스락3 으로 네가지 구분을 받아올 수 있습니다. 예를 들어서

if (Keyboard.getLedStatus() >= 2) { analogWrite(13, 128); }
else { analogWrite(13, 0); }

이렇게 하시면 13번에 연결된 LED를 캡스락 LED로 쓰실 수 있습니다.


---


5. 보다 효율적인 스캔

앞서 설명드린 if문은 analogRead를 매 줄 진행합니다. 요거 할 때 부담(딜레이)이 좀 있습니다. 그래서 키가 많아지고 코드가 복잡해지면 가끔 빠르게 입력하는 키가 씹히거나 할 수 있습니다. 그러니까 이걸 변수로 지정해서 한 번에 몰아서 스캔하는 방법이 있는데요

int AR0 = 0;

void setup() {
  pinMode(A0, INPUT_PULLUP);
}

void loop() {
  AR0 = analogRead(A0);
  if (AR0 > 1000) {
    Keyboard.release();
  }
  else if (AR0 < 20) { }
  else if (AR0 < 220) { }
}

처럼 AR0이라고 앞에서 변수를 선언한 다음 1바퀴 돌 때 1번만 스캔하면 전체적인 루프 시간이 빨라집니다. 또 아무 키를 입력하지 않은 " > 1000" 부분을 맨 앞으로 오게 하고, 그 뒤로 키 입력이 생기는 낮은 숫자를 배치하면 평소 아무 키도 안눌렀을 때 if 체크가 많이 생략되어 조금 빨라집니다.

또한 키 체크 하실때에도 예를 들어 (AR0 < 220) 보다는 (AR0 > 205 && AR0 < 215) 처럼 오차범위 내에서 최대한 줄여서 if를 체크하시면 혹시 생길 수 있는 고스트키 현상을 최대한 억제할 수 있습니다.


---


6. 매크로


지금 스위치를 누르면 원하는 글자가 입력되고 스위치를 떼면 입력이 멈추는 장치를 만들었는데 매크로를 지원합니까? 같은 이야기를 해선 곤란하겠죠.


디지털핀0번에 연결된 키를 누르면 메모장을 실행하고, "Hello, world!" 하고 말 한 다음 5초 기다리고서 www.google.com 을 인터넷 익스플로러로 띄우는 기능을 만들어봅시다.


void setup() {
  pinMode(0, INPUT_PULLUP); // 0번 핀을 입력핀으로 선언합니다
}

void loop() {
  if (digitalRead(0) == 1) { //  0번 핀이 스위치가 안눌려서 5볼트 그대로면
  } // 암것도 안합니다
  else { // 스위치가 눌리면
    Keyboard.releaseAll(); // 일단 혹시 모르니 다른 모든 키를 뗌 처리합니다

    Keyboard.press(KEY_LEFT_GUI); // 윈도우 키를 누릅니다

    Keyboard.press('r'); // R키를 누릅니다 (윈도우+R = 실행)

    Keyboard.releaseAll(); // 키 다시 뗍니다

    Keyboard.println("notepad"); // notepad하고 적습니다. 지금 실행창 열린 상태니 이러면 메모장이 실행되겠죠.

    // print 하시면 그냥 입력만 되고, println 하시면 입력+엔터 됩니다

    delay(500); // 메모장 열리는동안 0.5초간 기다립니다

    Keyboard.println("Hello, world!"); // 글자 타이핑합니다

    delay(5000); // 5초간 기다립니다

    Keyboard.press(KEY_LEFT_GUI); // 윈도우

    Keyboard.press('r'); // R

    Keyboard.releaseAll(); // 키 떼고

    Keyboard.println("iexplore http://www.google.com"); // 익스 실행

  }

}


자 그럼 응용해서 원하는 키에 원하는 기능이 들어가게 하실 수 있겠죠? 키 하나씩 누를땐 Keyboard.write, 문장 타이핑을 할 땐 Keyboard.println, 조합키를 누를땐 Keyboard.press + release 입니다.



---


도전과제 :

키보드로 마우스 만들기
ALT키와 GUI(Windows) 키 합치기
일반 숫자를 넘버패드 숫자 스캔코드로 입력되게 하기
키를 1초 이내에 한 번 치면 ㄱ, 두 번 치면 ㅋ, 세번 치면 ㄲ로 입력하게 하기