[아두이노] 아두이노 매크로 키보드 제어

IOT/아두이노|2019. 6. 28. 09:00

[아두이노]아두이노 매크로 키보드 제어



지난 시간까지 해서 아두이노 기본 키보드/마우스 동작 명령을 실험을 해보았습니다. 오늘은 아두이노 IDE의 USB 예제에서 "KeyboardReprogram" 소스가 있는데 매크로 키보드 제어 예제로 딱 좋을 것 같아서 소개를 하도록 하겠습니다. 아두이노를 이용하여 PC에서 수행 할 명령을 기록해 놓았다가 기록 된 순서대로 명령을 내릴 수 있습니다. 이 원리를 이용하면 상상력에 따라 다양한 오토 매크로 프로그램을 만들 수 있습니다.

오늘 실험 할 내용을 "KeyboardReprogram" 예제는 동작은 현재 사용되는 보드에 새로운 프로그램을 스스로 업로드하는 시키는 예제입니다. 이 예제를 약간 변형시켜서 아두이노 마이크로에서 아두이노우노에 프로그램을 매크로를 통해서 이식하는 실험을 해보도록 하겠습니다.


아두이노 마이크로에서 매크로 키보드를 이용하여 아두이노우노에 프로그램을 이식 시키는 실험입니다.

1. 아두이노 매크로 키보드 회로도


  • 준비물 : 스위치버턴 3개, LED 2개, 저항 220옴 2개, 아두이노 마이크로, 아두이노우노
  • 내용 : 스위치버턴을 아두이노 마이크로 2,3,4번핀에 순서대로 연결하고 LED은 11, 12번에 연결하시오


아두이노 마이크로 2(인터럽트핀), 3(A코딩매크로스위치), 4(B코딩매크로스위치) 번 핀을 사용합니다.
아두이노우노 9(RedLED핀), 10(GreeenLED핀) 번 핀을 사용합니다.

2. 코딩



위 사이트에 가시면 "KeyboardReprogram" 예제에 대해서 설명이 나와 있습니다. 이 예제는 간단히 설명을 하면 스위치 버턴을 누르면 아두이노 IDE 창에서 새로운 창을 열고 거기에 특정 아두이노 소스를 코딩하고 코딩된 명령을 현재 보드에 새롭게 업로드하게 됩니다. 즉, 현재 아두이노보드에 인식된 프로그렘에서 다시 새로운 프로그램이 이식되도록 하는 명령을 내린다고 이해하시면 됩니다. 한번 위 사이트에 가셔서 어떻게 코딩되어 있는지 살펴보시기 바랍니다.

본격적으로, "KeyboardReprogram" 예제 소스를 기반으로 설명합니다. 전체소스는 위 공식홈페이지에 가셔서 예제를 보시기 바랍니다. 좋은 예제여서 새롭게 뭘 만들기 보다는 이 예제로 자세히 설명하는 위주로 우선 이야기 하겠습니다.

"KeyboardReprogram" 예제 소스를 보면아두이노에서 새로운 프로그램을 이식하는 매크로 코딩을 하면 다음과 같습니다.

  • 아두이노 새창 띄우기
  • 아두이노 새창에 코딩 지우기
  • 아두이노 매크로 이식 코딩
  • 자동 포맷
  • 업로드(추가 저장하기)

1) 아두이노 IDE 새창 띄우기


현재 아두이노 IDE 창이 있다면 아래 명령을 수행하면 새로운 아두이노 IDE 편집창이 뜹니다.

[Ctrl+n(새창)]

  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press('n');
  delay(100);
  Keyboard.releaseAll();  
  delay(1000);

2) 아두이노 새창에 코딩 지우기


새로운 창에는 기본 아두이노 코딩이 되어 있습니다. 이 코딩은 지우셔야 합니다. 지우기 위해서 코딩 전체 영역을 지정하기 위해서 "Ctrl+a"키를 누르면 새로운 창에서 전체 영역을 지정합니다. 그리고 나서 KEY_BACKSPACE 키를 누르면 전체 지정된 영역은 삭제 됩니다. 이 과정을 코딩으로 표현하면 아래와 같습니다.

[Ctrl+a 키 동작(창안 전체 영역 지정)]

  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press('a');
  delay(500);
  Keyboard.releaseAll();

[지우기]

  Keyboard.write(KEY_BACKSPACE);
  delay(500);

3) 아두이노 매크로 이식 코딩


간단한 프로그램을 이식하는 예제로는 blink만한게 없죠. 그 예제로 하번 코딩해 볼까요.

[blink소스]

void setup(){
  pinMode(10, OUTPUT);
}
void loop(){
  digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(10, LOW);
  delay(1000);
}

blink 코딩 소스를 아두이노 이식 시키는 매크로 코딩을 하면 아래 와 같습니다.

Keyboard.println("void setup() {");
Keyboard.println("pinMode(10, OUTPUT);");
Keyboard.println("}");
Keyboard.println();
Keyboard.println("void loop() {");
Keyboard.println("digitalWrite(10, HIGH);");
Keyboard.print("delay(1000);");
Keyboard.println("digitalWrite(10, LOW);");
Keyboard.print("delay(1000);");
Keyboard.println("}");

어렵지 않죠. 아두이노 IDE 편집창에서 실제 키보드로 치는 것처럼 위 코딩을 치면 됩니다.

4) 자동 포맷


[Ctral+t(자동포맷)]

Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('t');
delay(100);
Keyboard.releaseAll();
delay(3000);

5) 업로드(추가 저장하기)


아두이노 IDE에서 업로드 단축키를 누르면 저장창이 뜹니다. 이때 랜덤이름으로 KEY_RETURN키로 저장하고 계속 진행하게 한다면 아래와 같이 코딩하면 됩니다.

[Ctrl+u(업로드)]

Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('u');    
delay(100);
Keyboard.releaseAll();
delay(1000);

Keyboard.press(KEY_RETURN);
delay(100);
Keyboard.releaseAll();

만약, 저장하기를 안하고 계속 진행할려면 저장하기 창에서 KEY_ESC키를 누르시면 해당 창이 취소됩니다. 그리고 나서 계속 업로드가 진행이 이루어 집니다.

Keyboard.press(KEY_ESC);
delay(100);
Keyboard.releaseAll();

6) 아두이노 마이크로에서 아두이노 우노에 blink 코딩 업로드 시키기


위 "KeyboardReprogram" 예제 소스의 원리를 이해 하셨으면 약간 변형하여 아두이노 마이크로에서 아두이노 우노에 두개의 프로그램을 업로드 시키는 과정을 매크로 코딩으로 만들어 실험을 해봅시다. 이식 할 프로그램은 blink 예제 소스로 두가지 형태의 프로그램을 이식 하겠습니다.

  • A 코딩 : Red LED를 1초 단위로 깜박이게 하기
  • B 코딩 : Green LED를 1초 단위로 깜박이게 하기

기본 과정은 위에서 코딩 설명한 과정을 그대로 적용합니다.

  • 아두이노 새창 띄우기
  • 아두이노 새창에 코딩 지우기
  • 아두이노 매크로 이식 코딩
  • 자동 포맷
  • 업로드 & 저장취소

여기서 새창에 매크로 이식 코딩을 A 상황과 B상황으로 코딩이 이루어지게 할 예정입니다. 즉, Pin_A, Pin_B 스위치를 클릭하면 A와 B blink 코딩이 아두이노우노에 업로드 되고 해당 9(Red), 10(Green) LED가 깜박이게 하기 위해서 매크로 이식 코딩을 외부 사용자 정의함수로 빼서 해당 핀값만 수정하여 코딩하도록 만들어 보았습니다.

기본 코딩 과정 설명은 위에서 설명을 했기 때문에 종합한 소스를 위 코딩한 내용을 기반으로 살펴보시기 바립니다.

#include "Keyboard.h"

const byte Pin_A = 3;
const byte Pin_B = 4;

const byte interruptPin = 2;
boolean state = true;

void setup() {
  pinMode(Pin_A, INPUT_PULLUP);
  pinMode(Pin_B, INPUT_PULLUP);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);

  Keyboard.begin();
}

void loop() {
  if (state == false) { //키보드 안전장치
    if (digitalRead(Pin_A) == LOW) { //A코딩 이식 명령
      delay(1000);
      programming(9); //제어핀은 9번으로 blink 코딩
      delay(5000);
    }
    if (digitalRead(Pin_B) == LOW) { //B코딩 이식 명령
      delay(1000);
      programming(10);      //제어핀은 10번으로 blink 코딩
      delay(5000);
    }
  }
}

//매크로 이식 코딩
void programming(int Pin_Val) {
  //Ctrl+N 새창 열기
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press('n');
  delay(100);
  Keyboard.releaseAll();
  delay(1000);
  
  //Ctrl+A 키 동작(코딩창 안의 전체 영역 지정)
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press('a');
  delay(500);
  Keyboard.releaseAll();

  //지우기
  Keyboard.write(KEY_BACKSPACE);
  delay(500);

  //이식 할 코딩
  Keyboard.println("void setup() {");
  Keyboard.print("pinMode(");
  Keyboard.print(Pin_Val);
  Keyboard.println(",OUTPUT);");
  Keyboard.println("}");
  Keyboard.println();
  Keyboard.println("void loop() {");
  Keyboard.print("digitalWrite(");
  Keyboard.print(Pin_Val);
  Keyboard.println(",HIGH);");
  Keyboard.print("delay(1000);");
  Keyboard.print("digitalWrite(");
  Keyboard.print(Pin_Val);
  Keyboard.println(",LOW);");
  Keyboard.print("delay(1000);");
  Keyboard.println("}");

  //자동포맷
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press('t');
  delay(100);
  Keyboard.releaseAll();
  delay(3000);
  
  //업로드
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press('u');
  delay(100);
  Keyboard.releaseAll();
 
  delay(500);
  Keyboard.press(KEY_ESC); //저장취소
  delay(100);
  Keyboard.releaseAll();
}
void exchange() {
  state = !state;
}

보시면 programming(9), programming(10)으로 해서 Pin값만 바꿔서 코딩을 하고 해당 코딩을 아두이노 우노에 이식하게 됩니다.

4. 결과


결과는 좀 복잡한 과정을 거칩니다. 왜냐면 위 코딩은 우선 아두이노 마이크로 이식합니다.


위와 같이 보드/포트를 지정하고 아두이노 마이크로에 이식을 먼저 한 다음에 아두이노우노에 프로그램을 이식하기 위해서는 아두이노 IDE 창에 보드/포트를 아두이노우노 보드에 맞춰서 미리 세팅을 해놔야 합니다.


1) A 코딩



A버턴을 누르면


자세히 보시면 핀 번호가 9번이 보일꺼에요.

2) B 코딩



B버턴을 누르면


자세히 보시면 핀 번호가 10번이 보일꺼에요.

3) 결과


A, B 버턴을 누르고 해당 매크로 코딩 이식과정을 PC 창에서 진행 되는 모습을 보시면 한줄로 쭉 코딩이 되어지네요. println()함수를 치면 다음라인으로 넘어 갈 줄 알았는데 다음 라인으로 커서가 넘어가지 않더군요.

억지로 한줄 끝날때마다

  Keyboard.press(KEY_RETURN);
  delay(100);
  Keyboard.releaseAll();

이 명령으로 커서를 강제로 넘길 수 있지만 그러면 코딩이 너무 길어지기 때문에 그리고 어짜피 가독성이 떨어지게 코딩 한다고 해서 이식이 안되는 것도 아니기 때문에 그냥 억지로 다음라인으로 넘기는 코딩은 하지 않았습니다.

그리고, 아두이노 IDE가 매번 클릭 할 때마다 새로운 창이 뜹니다. 이부분도 사실 이식이 끝나면 해당 코딩창을 "Ctrl+q"로 창 닫기를 누르면 되는데 이 부분도 생략했네요. 이 부분을 하려면 프로그램이 어느정도 정상적으로 이식과정이 끝났다는 것을 확인이 필요합니다. 그냥 대충 창 종료를 누르면 업로드 중간에 창이 닫히기 때문에 오류 발생을 줄이고 간단히 특정 동작을 실험하는게 목적이기 때문에 여러가지 문제 상황에 대해서 정교하게 코딩은 하지 않았습니다. 기본 의미 전달이 목적이기 때문입니다.단순히 아두이노 마이크로에서 아두이노우노에 새롭운 프로그램을 이식 시킬 수 있는지 보기 위한 실험이기 때문에 복잡한 코딩은 생략합니다.

아래 동영상에서 3개의 버턴 중 하나는 인터럽트 버턴으로 키보드 동작 명령에 에러가 발생할 때 중지할 수 있는 버턴으로 활용하고 나머지 2개의 버턴은 A코딩 이식과 B코딩 이식하는 과정의 매크로 명령을 수행합니다. Red LED가 1초 단위로 깜박이는 코딩과 Green LED가 1초 단위로 깜박이는 코딩인데 실제로 스위치 버턴을 누를 때 아두이노우노에 프로그램을 이식하는데 이식이 정상적으로 되었는지 어떤 LED가 깜박이는지 보시면 눈으로 확인 하실 수 있을꺼에요. PC랑 실제 스위치를 누르는 장면을 같이 담아야 하는데 폰이 구려서 같이 찍으면 PC 모니터의 진행 과정이 흐리게 나오기 때문에 그냥 LED의 변화의 모습으로 아두이노우노에 코딩이식이 이루어지는지 확인하실 수 있습니다.


마무리


아두이노 마이크로에서 아두이노우노에 프로그램을 이식시키는 과정을 실험 했습니다. 참고로, "KeyboardReprogram" 예제 소스는 자기 자신에 새로운 프로그램을 이식하는 예제입니다. 자기 자신의 보드에 프로그램을 이식 원리와 다른 보드에 프로그램을 이식시키는 원리를 이번 시간에 제대로 이해하셨으면 합니다.

자기 자신에 새로운 프로그램을 이식하는 경우는 어떤 특정한 프로그램을 아두이노 마이크로 업로드 했을 때 프로그램이 어떤 동작에 약간 오차값이나 보정이 필요할 경우 지금까지는 변수를 만들어 넣고 그 변수의 보정값을 저장하여 다음 동작을 수행했습니다. 매번 전원이 새롭게 공급할 때마다 이 과정을 반복합니다. 그런데 자기 자신에 새로운 프로그램을 이식할 수 있다면 처음 한번만 조정이 되고 그 값을 기준으로 새롭게 프로그램을 스스로 재이식할 수 있게 되면은 해당 아두이노보드는 스스로 진화하게 됩니다. 여기서 아두이노 IDE로 프로그램을 업로드 했지만 따로 컴파일과 이식하는 과정을 아두이노 IDE를 통하지 않고 직접 수행 할 수 있는 방법을 찾아 낸다면 직접 스스로 새로운 프로그램으로 업로드하여 아두이노가 스스로 업데이트 할 수 있게 되겠죠.

다른보드에 프로그램을 이식하는 경우는 새로운 보드에 원하는 형태로 프로그램을 자동으로 A보드는 A코딩을 B보드는 B코딩을 이식할 수 있게 됩니다. 학습할 수 있는 아두이노라면 학습을 통해서 원하는 방향으로 다른 보드에 프로그램을 이식시킬 수 있게 된다면 상상을 해보세요. 위 두 과정을 상상하면 약간 테미네이트 영화처럼 되지 않을가 싶네요. 기계가 다른 기계에 프로그램을 이식하는 것은 엄청난 것입니다.

아무튼 오늘은 매크로 코딩 이식과정을 실험했지만 꽤 중요하고 상상을 하기에 따라 엄청난 결과물을 만들어 낼 수도 있습니다. 한번 상상의 나래를 펼쳐서 자신의 상상력이 어디까지 바라볼 수 있는지 도전해 보세요.


댓글()

[아두이노] 아두이노 키보드 제어

IOT/아두이노|2019. 6. 24. 09:00

[아두이노] 아두이노 키보드 제어



지난 시간에 아두이노 마이크로 보드를 간단히 테스트를 했으니 이제 본격적으로 키보드 제어를 실험해 봅시다. 아두이도 키보드/마우스 제어를 하기 위한 목적으로 아두이노 마이크로 보드를 구매 했습니다. 오늘은 키보드 제어에 대해서 이야기를 할까 합니다. 프로그램언어를 공부하신분들은 오토키보드, 오토마우스 프로그램을 한번쯤을 사용해 보셨을 꺼에요. 게임을 할 때 오토 매크로 프로그램으로 게임을 자동사냥에 이용을 해보셨던 분도 아마 있을 꺼에요. C언어에서 키관련 핸들러를 이용해서 오토매크로 프로그램을 만들 수 있습니다. 이걸 코딩하기 위해서는 좀 코딩하기도 힘들고 복잡합니다. 저도 예전에 학창시절에 한번 코딩해보고 이제는 코딩 기억도 안나는 그런 것들이 있었지 정도에 기억만 남았네요.

그런데 아두이노에서 키보드 제어를 무지 쉽게 할 수 있는 방법을 제공합니다. 키보드 라이브러리가 오픈소스로 제공되고 단지 여러분들은 함수 몇개만 알고 있으면 쉽게 키보드 제어를 할 수 있습니다. 키보드 제어 코딩이 쉽지 않는데 이렇게 비전공자들도 쉽게 제어할 수 있는 방법을 제공하니 진짜 아두이노는 못하는 것이 없는 만능 싱글보드라고 생각됩니다.

이제 본격적으로 키보드 제어를 해볼까요.


1. 아두이노 키보드 제어



위 사전학습으로 읽고 오시면 됩니다. 사전학습 자료를 보시면 8개의 함수가 있는데 이 함수만 알면 키보드 제어를 마음대로 할 수 있습니다. 간단히 함수에 대해 살펴 볼까요.

  • 키보드 시작 : Keyboard.begin()
  • 키보드 종료 : Keyboard.end()
  • 키 누름 : Keyboard.press()
  • 키 해제 : Keyboard.release()
  • 키 전체 해제 : Keyboard.releaseAll()
  • 키 문자열 출력 : Keyboard.print(), Keyboard.println() , Keyboard.write()

함수도 그렇게 어렵지 않죠. 기본적으로 3개의 함수만 알고 있으면 키보드 키를 마음대로 제어할 수 있습니다.

1) 키 제어


키보드의 키를 제어하는 방법을 살펴보도록 하죠.

[기본소스]

#include <Keyboard.h>

void setup(){
 Keyboard.begin();
}
void loop(){
  if(버턴누름){
    Keyboard.press('a'); //키 누름
    delay(100);
    Keyboard.releaseAll(); //키 해제
    delay(200);     
  }
}

위 소스가 기본 키보드 누르는 동작입니다. press('a')함수는 'a'키 누르는 명령입니다. 이렇게만 코딩하면 a키가 눌려 있는 상태가 됩니다. 키누를 눌렀으면 때는 동작을 해야 겠죠. releaseAll()함수로 현재 눌려진 키들을 전부 해제하는 명령입니다.

즉, "ctrl+n" 키를 누를때 사용하면 좋겠죠.

Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('n');
delay(100);
Keyboard.releaseAll(); //키 해제

어떤 느낌이신지 아시겠지요.

2) 문자열 제어


아두이노는 미리 만든 문자열을 키보드로 친것과 같이 한번에 출력할 수 있습니다. 느낌으로 표현하자면 Ctrl+V의 느낌이라고 생각하시면 됩니다. 키보드 커서가 있는 위치에 아두이노에 저장된 문자열이 Ctrl+V를 누른 것 같이 문자열을 해당 커서 위치에 출력하게 됩니다.

Keyboard.println("STEEMIT!");

[결과]


어떤 느낌인지 아시겠지요.

3) 키보드 키값



위 github에 가시면 키보드 키값을 확인하실 수 있습니다. 아니면 아두이노 IDE 라이브러리 폴더에 가셔서 Keyboard.h 파일을 열어보셔서 됩니다.

열어보시면 키보드 키들이 정의 되어 있는데 아래 그림과 같습니다.


위 그림은 알파벳을 제외한 그외 일부 키들에 대한 부분입니다. 알파벳은 그냥 알파벳을 쓰면 되고 나머지 키들은 위에서 정의한 이름으로 키를 사용하시면 됩니다.

2. 아두이노 키보드 제어 회로도


  • 준비물 : 스위치버턴 5개, 아두이노 마이크로
  • 내용 : 스위치버턴을 아두이노 마이크로 2,3,4,5,6번핀에 순서대로 연결하시오.

지난시간에 보여준 아래 그림은 다시 복습차원으로 보시기 바랍니다.



아두이노 마이크로 핀 연결할 때 핀 번호를 위에 복습차원으로 올린 아두이노 마이크로 정보를 보시고 핀 연결하시면 됩니다.

3. 코딩


스위치버턴을 5개를 키보드 키를 제어하는데 사용 합니다. 처음에 알파벳 a,b,c,d 키와 KEY_RETURN 키로 실험을 하려다가 설계를 2번핀은 인터럽트 핀으로 사용하고 안정장치를 마련하고 나머지 3,4번은 a,b 키, 5번은 KEY_RETURN 키, 6번은 KEY_BACKSPACE 키로 사용하여 최대한 키보드 느낌을 살리는 실험을 하겠습니다.

1) 키보드 안전장치


키보드를 아두이노를 제어를 하게 되면 약간 주의해서 코딩을 해야 합니다. 잘못된 코딩을 하게 되면 무한 루프에 빠져서 키를 무한으로 누르는 문제가 발생 시킬 수 있습니다. 의도치 않게 잘못된 무한 버그가 발생 할 수 있으니 코딩을 할 때 주의해서 코딩을 해야 합니다. 그래서 안전장치로 인터럽트를 이용할까 합니다. loop()함수가 무한 반복 수행 하더라고 중간에 인터럽트 이벤트를 발생시킬 수 있습니다. 그러면 이 이벤트 명령으로 반복 수행을 중단시킬 수 있습니다. 즉, loop()함수에 락을 하나 걸어놓고 문제가 생기면 락을 걸어서 아두이노의 키보드 명령을 중단시키면 문제에 대해서 탈출 할 수 있습니다.

[기본소스]

const byte interruptPin = 2;
boolean state = true;

void setup() {   
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);  
}
void loop(){
  if(state==false){
    
    키보드 명령;
    
    }
}
void exchange() {
 state=!state;
}

위 코딩을 보면 state가 false일때만 키보드 명령이 수행되고 키보드 명령이 잘못된 코딩으로 오류로 무한 루프에 빠지게 되면 인터럽트 스위치버턴을 누르면 state는 true 상태가 되고 더이상 키보드 명령을 수행하지 않게 됩니다.

이 안전장치가 어떤 느낌인지 아시겠지요. 나중에 코딩이 완성되면 키보드 안정장치 코딩은 지우셔도 됩니다. 코딩하면서 테스트할 때 혹시 모를 error에 대한 대비책으로 생각하시면 됩니다.

참고로, 아두이노 마이크로에서 선언때 초기값이 state가 true인데 loop()함수 내에서 state의 초기 상태는 false입니다. 아두이노우노에서는 loop()에서도 true 상태를 유지하는데 이상하게 아두이노 마이크로는 인터럽트가 한번 수행하고 들어가는 것 같더군요. 혼동하지 마세요.

2) 키보드 키 실험


  • 알파벳(a,b 키), KEY_RETURN, KEY_BACKSPACE 키로 간단히 키보드 테스트

핀번호을 선언 합니다.

const byte Pin_A = 3;
const byte Pin_B = 4;
const byte Pin_Return = 5;
const byte Pin_Backspace = 6;

스위치 버턴 모두 내부풀업모드 방식을 사용하니깐 pinMode()은 다음과 같이 INPUT_PULLUP 모드로 선언 합니다.

pinMode(Pin_A, INPUT_PULLUP); pinMode(Pin_B, INPUT_PULLUP); pinMode(Pin_Return, INPUT_PULLUP); pinMode(Pin_Backspace, INPUT_PULLUP);

'a'키 누름 이벤트 명령은 다음과 같습니다. 내부풀업모드로 초기상태가 HIGH 입니다. 그래서 스위치를 누르면 LOW로 바뀌게 되고 IF문이 참이 되어 키 누름과 해제 명령을 수행하게 됩니다.

 if(digitalRead(Pin_A) == LOW){
    Keyboard.press('a');
    delay(100);
    Keyboard.releaseAll();
    delay(200);  
 }

여기서, 일정 딜레이 시간을 둔 이유는 키보드 누름 간격을 주기 위해서 입니다. 딜레이 시간이 없게 되면 너무 빠른 속도로 눌러지기 때문에 a라는 키가 연속으로 눌러지는 현상이 발생합니다. 너무 길레 딜레이를 주면 지연이 발생하고 너무 짧게 딜에이를 주면 연속 키 누름 현상이 발생합니다. 위 시간값은 제 편의상 지정한 값임으로 키 누름 딜레이 시간을 조절해 보세요. 참고로 실제 키보드 보다는 좀 느린 편입니다. 키누름 반응속도가 좀 느린 편이죠. 그런데 너무 짧게 하면은 정상적인 알파벳 입력이 어려우니깐 상황에 따라서 조절하시면 될 듯 싶습니다. 참고로, 게임 조종기로 사용할 경우는 반응속도를 높이기 위해서 딜레이 간격을 줄이는게 좋습니다.

나머지 스위치 버턴도 위와 같이 동일하게 코딩하면 됩니다.

3) 종합소스


위 안전장치 코딩과 키 누름 코딩을 합쳐서 종합해 보면 아래와 같이 코딩을 할 수 있습니다.

#include <Keyboard.h>

const byte Pin_A = 3;
const byte Pin_B = 4;
const byte Pin_Return = 5;
const byte Pin_Backspace = 6;

const byte interruptPin = 2;
boolean state = true;

void setup() {  
  Serial.begin(9600);
  Keyboard.begin();
  pinMode(Pin_A, INPUT_PULLUP); 
  pinMode(Pin_B, INPUT_PULLUP);
  pinMode(Pin_Return, INPUT_PULLUP);
  pinMode(Pin_Backspace, INPUT_PULLUP);

  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);  
}

void loop() {
  if(state==false){
    if(digitalRead(Pin_A) == LOW){
      Keyboard.press('a');
      delay(100);
      Keyboard.releaseAll();
      delay(200);  
    }
    if(digitalRead(Pin_B) == LOW){
      Keyboard.press('b');
      delay(100);
      Keyboard.releaseAll();
      delay(200);  
    }
    if(digitalRead(Pin_Return) == LOW){
      Keyboard.press(KEY_RETURN);
      delay(100);
      Keyboard.releaseAll();
      delay(200);  
    }
    if(digitalRead(Pin_Backspace) == LOW){
      Keyboard.press(KEY_BACKSPACE);
      delay(100);
      Keyboard.releaseAll();
      delay(200);  
    }   
  }
}
void exchange() {
 state=!state;
}

스위치 버턴 누름을 delay()함수로 간단히 테스트 했기 때문에 각 키간의 지연 렉이 좀 발생할 수 있습니다. 시간 간격이 워낙 짧기 때문에 체감이 잘 안될 수 있지만 더 정교하게 제어를 원하시는 분이라면 delay()함수 대신에 저번에 설명한 millis()함수로 이용하여 delay()함수 없이 delay를 제어하는 방법으로 코딩을 수정하면 됩니다.

이 코딩은 단지 동작을 테스트 할 목적의 코딩이기 때문에 복잡한 동작 명령은 생략합니다.

4. 결과



스위치버턴은 말풍선의 순서대로 해당 키보드 키명령을 가지고 있습니다. 해당 스위치 버턴을 해당 명령을 PC에서 수행합니다.

결과는 아래 동영상에서 확인하시면 됩니다.


마무리


완벽하지는 않지만 그래도 키보드 같은 느낌으로 제작이 되었네요. 코딩을 좀 더 정리를 해야 하고 약간 문제되는 부분을 수정 보안해야 하는데 간단한 실험을 하기 위해서 코딩은 수정하지 않았습니다. 그리고, 아두이노 IDE 예제들에서 USB 예제를 보시면 키보드 예제 소스들이 몇가지가 있는데 재밌는 예제들인데 한번 전부 다 테스트 해보셨으면 합니다. 꽤 재밌는 원리가 숨어 있습니다. 예제 중 하나만 설명드리면 아두이노 마이크로가 아두이노 IDE 창에 새로운 창을 띄우게 하고 아두이노 자기 스스로 코딩을 하고 그 코딩을 직접 아두이노 마이크로에 업로드를 시킵니다. 그리고 아두이노 마이크로가 직접 스스로 코딩한 명령을 수행하게 됩니다. 이게 뭘 의미 하냐면 아두이노 마이크로가 자기 스스로 업그레이드를 수행한다는 것을 의미합니다. 만약, 학습능력을 아두이노 마이크로에 코딩되어 있으면 그 학습에 의해서 스스로 자기 자신을 코딩하여 업그레이드가 가능해진다는 의미가 됩니다. 한마디로 아두이노 마이크로가 스스로 진화할 수 있다는 의미와 같습니다.

자기 자신에게 프로그램을 코딩하고 이식한다는 것은 엄청난 원리입니다. 스스로 업그레이드를 할 수 있다는 의미이고 진화를 할 수 있다는 의미와 같습니다. 한번 이 원리를 상상의 나래를 펼쳐 보세요.


댓글()