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

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코딩을 이식할 수 있게 됩니다. 학습할 수 있는 아두이노라면 학습을 통해서 원하는 방향으로 다른 보드에 프로그램을 이식시킬 수 있게 된다면 상상을 해보세요. 위 두 과정을 상상하면 약간 테미네이트 영화처럼 되지 않을가 싶네요. 기계가 다른 기계에 프로그램을 이식하는 것은 엄청난 것입니다.

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


댓글()