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

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. 25. 09:00

[아두이노] 아두이노 마우스 제어



지난 시간에 아두이노 마이크로 보드로 키보드 제어를 해 보았습니다. 오늘은 마우스를 제어해보는 시간을 갖도록 하죠. 키보드와 마찬가지로 마우스도 몇개의 함수만 이해하시면 쉽게 아두이노를 이용해서 마우스의 동작을 수행할 수 있습니다.

이제 본격적으로 마우스 제어를 해볼까요.


1. 아두이노 키보드 제어



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

  • button : MOUSE_LEFT (default), MOUSE_RIGHT, MOUSE_MIDDLE
  • 마우스 시작 : Mouse.begin()
  • 마우스 클릭 : Mouse.click() or Mouse.click(button)
  • 마우스 종료 : Mouse.end()
  • 마우스 이동 : Mouse.move(xVal, yPos, wheel) - x축, 축, 스크롤 휠의 움직임 양
  • 마우스 버턴 클릭 : Mouse.press() or Mouse.press(button)
  • 마우스 버턴 해제 : Mouse.release() or Mouse.release(button)
  • 현재 마우스가 눌러진 정보 반환 : Mouse.isPressed() or Mouse.isPressed(button)

함수도 그렇게 어렵지 않죠. 기본적으로 마우스 클릭과 마우스 이동에 관한 함수만 이해하시면 됩니다.

1) 마우스 이동 제어


마우스 이동 제어하는 방법은 다음과 같습니다.

[기본소스]

#include <Mouse.h>

void setup(){
  Mouse.begin();
}
void loop(){
  if(버턴누름){
    Mouse.move(x, y, 스크롤휠);
  }
}

위 소스가 기본 마우스 이동 동작입니다. 마우스로 위로 이동한다면 어떻게 코딩할까요.

if(digitalRead(Pin_Up) == LOW){ //위로
  Mouse.move(0, -1, 0);
}

참골, 위/아래, 좌/우로 움직임을 x,y값만 바꾸시면 되고, 위로 이동하는 위 명령문을 수정하여 코딩하시면 나머지 동작 명령을 수행할 수 있게 됩니다.

2) 마우스 클릭 제어


[기본소스]

#include <Mouse.h>

void setup(){
  Mouse.begin();
}

void loop(){ 
  if(버턴누름){
    Mouse.click();
  }
}

기본 보스를 보면 Mouse.click()함수는 디폴트로 MOUSE_LEFT 클릭이 됩니다. 특정 키를 누르고 싶다면 어떻게 코딩할까요.

Mouse.click(MOUSE_RIGHT);

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

  • button : MOUSE_LEFT (default), MOUSE_RIGHT, MOUSE_MIDDLE

기본적으로 버턴은 위의 세가지 왼쪽, 오른쪽, 중앙 버턴으로 나뉘고 지정해주면 해당 버턴이 클릭됩니다. 지정하지 않으면 디폴트로 왼쪽 버턴을 클릭하신다고 보시면 됩니다.

추가로, Mouse.click()함수는 클릭 이벤트입니다. 다른 방식으로 표현하면은 다음과 같습니다.

void loop(){ 
  if(버턴누름){
    Mouse.press(MOUSE_LEFT);
    delay(100);
    Mouse.release(MOUSE_LEFT);
    delay(200);
  }
}

마우스 키를 누름과 해제로 마우스 클릭 이벤트를 만들어 냅니다. 이와 같은 방식은 사실 클릭함수만 있으면 되지 구지 이 함수로 표현을 하냐 하실분들이 있을거에요. 누름(press)과 해제(release) 함수는 사용되는 곳이 따로 있습니다. 가령, 웹페이지가 있으면 특정 영역을 복사하기 위해서 어떻게 하나요 마우슨 왼쪽을 누른 상태에서 드래그를 하고 복사할 위치에서 마우스 누른 상태를 해제합니다. 이렇게 마우스의 클릭이 아니라 일정시간 마우스의 누름이 필요할 때는 사용되는 함수입니다. 클릭으로 사용해도 되고 또는 특정한 누름 일정시간 동안 유지가 필요할 때도 사용됩니다.

  if(버턴누름){
    Mouse.press(MOUSE_LEFT);        
  }else if(버턴 해제 && Mouse.isPressed()==1){
    Mouse.release(MOUSE_LEFT);
  } 

버턴을 누르고 있는 동안은 마우스 왼쪽 버턴이 클릭된 상태가 되겠죠. 이방식은 계속 클릭 명령을 내리기 때문에 별로 좋지 않습니다. 한 상태를 계속 유지하고 클릭을 반복 명령을 내리게 하고 싶지 않다면 아래와 같이 변경해야 합니다.

 if(버턴누름){
    if( Mouse.isPressed()==0) Mouse.press(MOUSE_LEFT);      
  }else if(버턴 해제 && Mouse.isPressed()==1){
    Mouse.release(MOUSE_LEFT);
  } 

이런게 마우스 클릭 상태정보가 0이면 클릭상태가 아니기 때문에 마우스왼쪽 버턴을 클릭하고 클릭상태가 1이면 클릭되어 있으니깐 계속 그 상태를 유지되고 있으니 구지 다시 클릭명령을 내릴 필요가 없습니다.

3) 마우스 상태 정보 반환


Mouse.isPressed() or Mouse.isPressed(button) 함수로 현재 마우스 상태 정보를 읽어 올 수 있습니다. 만약에 마우스 왼쪽 버턴을 눌렀다면 왼쪽버턴을 누른 상태 정보를 반환해 오겠죠.

정확히 어떤 값을 갖는지 살펴볼까요.

if(digitalRead(버턴핀) == LOW){ //버턴클릭
  Mouse.press(MOUSE_LEFT);
  Serial.println(Mouse.isPressed());
  delay(100);
  Mouse.release(MOUSE_LEFT);
  Serial.println(Mouse.isPressed());
  delay(200);     
}

[결과]

1
0

이렇게 출력됩니다 마우스를 press() 클릭하면 isPressed()함수로 해당 클릭 상태 정보 1을 반환합니다. 그리고 다시 release()함수로 해제하니깐 isPressed()함수로 반환되는 값은 0이 됩니다.

마우스 상태 정보 반환하는 함수는 해당 마우스버턴을 현재 클릭 정보를 통해서 다른 동작 명령을 다른 동작을 수행하거나 락을 걸어주거나 어떤 조건을 만들어 주기위해서 사용합니다. 위의 마우스 클릭 처럼 버턴을 클릭했다면 클릭했을 때 상태정보가 1이면 다음 클릭에서도 그 상태를 유지하니깐 구지 두번 명령을 내릴 필요가 없게 표현이 가능합니다. 그리고 어떤 클릭된 상태가 되었을 때 그 상태를 해제하고 싶을 때 먼저 클릭이 되었는지 확인하는 목적으로 사용됩니다. 클릭도 안했는데 클릭해제를 수행할 필요는 없겠죠.

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


  • 준비물 : 스위치버턴 5개, 아두이노 마이크로
  • 내용 : 스위치버턴을 아두이노 마이크로 2,3,4,5,6번핀에 순서대로 연결하시오.
  • 참고 : [아두이노] 아두이노 키보드 제어 회로도


지난 시간의 회로도를 그대로 적용합니다.

3. 코딩


스위치 버턴은 5개 입니다. 실험에서 2번 핀은 인터럽트 핀으로 사용하여 안전장치를 마련하고 나머지 3,4,5,6번 핀은 마우스 위치를 조절하는 핀으로 사용하겠습니다. 아쉬운 점은 스위치 버턴이 더 없어서 마우스클릭 이벤트까지는 적용을 못하였네요. 인터럽트 핀을 마우스 클릭 이벤트로 사용하면 좋은데 혹시 모를 에러를 예방하는 차원으로 안전장치가 필요하기 때문에 마우스 클릭 이벤트는 실험하지 않겠습니다.

1) 키보드 안전장치


지난 시간의 소스를 그대로 가져 왔네요. 복습차원으로 다시 봐 주시기 바랍니다.
[기본소스]

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;
}

위 코딩의 설명은 지난 시간 post를 보시기 바랍니다.

2) 마우스 이동 실험


  • Mouse.move(x, y, 휠) 함수로 마우스를 직접 움직이는 실험을 해 보겠습니다.

핀번호을 선언 합니다.

const byte Pin_Up = 3;
const byte Pin_Down = 4;
const byte Pin_Left = 5;
const byte Pin_Right = 6;

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

 pinMode(Pin_Up, INPUT_PULLUP); 
 pinMode(Pin_Down, INPUT_PULLUP);
 pinMode(Pin_Left, INPUT_PULLUP);
 pinMode(Pin_Right, INPUT_PULLUP);

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

 if(digitalRead(Pin_A) == LOW){
    Mouse.move(0, -1, 0);
 }

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

3) 종합소스


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

#include <Mouse.h>

const byte Pin_Up = 3;
const byte Pin_Down = 4;
const byte Pin_Left = 5;
const byte Pin_Right = 6;

const byte interruptPin = 2;
boolean state = true;

void setup() {    
  pinMode(Pin_Up, INPUT_PULLUP); 
  pinMode(Pin_Down, INPUT_PULLUP);
  pinMode(Pin_Left, INPUT_PULLUP);
  pinMode(Pin_Right, INPUT_PULLUP);

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

   Mouse.begin();
}

void loop() {
  if(state==true){
    if(digitalRead(Pin_Up) == LOW){ //위로
       Mouse.move(0, -1, 0);
    }else if(digitalRead(Pin_Down) == LOW){ //아래로
       Mouse.move(0, 1, 0);
    }
    if(digitalRead(Pin_Left) == LOW){ //왼쪽
       Mouse.move(-1, 0, 0);
    }else if(digitalRead(Pin_Right) == LOW){ //오른쪽
       Mouse.move(1, 0, 0);
    }   
  } 
}
void exchange() {
 state=!state;
}

스위치 버턴을 누름으로써 마우스의 해당 방향으로 움직이게 됩니다.

여기서, if문의 표현을 잘 봐주세요.

if문이 위/아래를 한쌍으로 묶었고 좌/우를 한쌍으로 묶었습니다. 왜 이렇게 했을까요. 바로 위를 누른 상태에서 아래를 누를 수 없고 좌를 누른 상태에서 우를 누를 수 없잖아요. 즉, 위/아래는 하나의 상태만 존재하고 좌/우는 하나의 상태만이 존재하기 때문에 위와 같이 IF 조건문으로 표현한 것이죠.

주의할점은, 4개의 상태를 if문으로 4개를 개별적으로 만들면 안됩니다.

예)

 if(digitalRead(Pin_Up) == LOW) {  }
 if(digitalRead(Pin_Down) == LOW) {  }

이렇게 코딩하면 안됩니다. 버턴을 동시에 누른다면 어떤 현상이 발생할까요. 두가지 상태를 모두 수행하기 때문에 어떤 의미로는 충돌에 가깝다고 보시면 됩니다. 그렇다고 해서 위 코딩이 동작하지 않는 것은 아닙니다. 의미상으로 코딩의 문제가 있는 것이죠. 어느시점에 오로지 딱 하나의 조건만이 있어야지 위/아래가 동시에 일어나는 것은 좀 문제가 있겠죠.

그리고, 위/아래의 하나의 상태와 좌/우의 하나의 상태는 동시에 일어날 수 있기 때문에 if문으로 분리해 줘야 합니다.

왜! 위에서 IF문을 저렇게 표현했는지에 대한 의미를 정확히 이해해 주세요.

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

4. 결과



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

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


영상을 보시면 처음 업로드 키를 눌러야 하는데 컴파일 키가 눌러졌네요. 이미 해당 코딩이 업로드 된 상태입니다. 업로드 부분부터 촬영을 하려고 하다 보니깐 실수가 발생했네요. 업로드가 이미 된 상태이다 보니깐 업로드 버턴이 아닌 컴파일 버턴을 누르고 영상을 계속 진행시켜 버렸네요. 재촬영하기 귀찮아서 그냥 올렸네요. 감안하시고 보세요. 참고로 한손에는 폰이 한손에는 마우스조정기가 있다 보니깐 대각선 움직임을 제대로 보여드리지 못했네요. 위/아래, 좌/우로만 움직였는데 실제로 조정하면 대각선으로도 움직입니다.

마무리


간단히 마우스 이동만 시켰네요. 키 누름 이벤트까지 3개를 만들고, 마우스 휠을 움직이는 명령까지 수행하게 했다면 완벽한 마우스가 완성되었겠죠. 약간 아쉬운 실험이 되었네요.

Mouse 라이브러리를 이용하니깐 Mouse.move()함수로 쉽게 PC 마우스를 움직일 수 있게 되었습니다. 이처럼 아두이노는 오픈소스로 많은 것들을 제공해주고 우리들은 제공된 라이브러리를 이용하여 쉽게 아두이노를 제어할 수 있습니다. 여러분들에게 필요한 것은 단지 뭘 만들고 싶은가의 상상만 필요할 뿐이죠.

여러분들은 지난시간에 배운 키보드 제어와 오늘 배운 마우스 제어를 통해 뭘 만들고 싶으신가요. 한번 상상의 나래를 펼쳐 보세요.


댓글()

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

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 창에 새로운 창을 띄우게 하고 아두이노 자기 스스로 코딩을 하고 그 코딩을 직접 아두이노 마이크로에 업로드를 시킵니다. 그리고 아두이노 마이크로가 직접 스스로 코딩한 명령을 수행하게 됩니다. 이게 뭘 의미 하냐면 아두이노 마이크로가 자기 스스로 업그레이드를 수행한다는 것을 의미합니다. 만약, 학습능력을 아두이노 마이크로에 코딩되어 있으면 그 학습에 의해서 스스로 자기 자신을 코딩하여 업그레이드가 가능해진다는 의미가 됩니다. 한마디로 아두이노 마이크로가 스스로 진화할 수 있다는 의미와 같습니다.

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


댓글()

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

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

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




최근에 몇개의 부품을 구매했는데 이제서야 아두이노 마이크로 보드를 소개 하네요. 사실 예전에 이 모델을 구매할려고 했지만 국내 가격이 해외직구 가격과 비교하면 3개를 구매 할 수 있는 가격으로 국내에서 판매하기 때문에 구매하기가 싫어지더군요. 지금까지 미뤄 왔는데 좀 비싸긴 하지만 오천원대 가격으로 어느정도 싸게 판매하는 곳이 있어서 그냥 구매하게 되었네요. 진짜 아두이노 부품을 사고 싶은 것들이 많은데 국내 가격은 해외 직구 가격 차를 보면 한숨만 나오네요.

오늘 실험은 간단히 아두이노 마이크로 보드가 정상적으로 동작하는지 테스트 실험을 하겠습니다.

1. 아두이노 마이크로 보드


오늘 소개 할 아두이노 마이크로 보드는 아두이노우노랑 비슷한 보드라고 생각하시면 됩니다. 차이점은 크기가 작고 USB가 다릅니다. 아두이노우노는 USB MCU ATmega16u2 방식인데 아두이노 마이크로는 Micro USB를 사용하면 ATMEGA32u4를 기반의 보드 입니다. 그래서, 아두이노 마이크로 보드를 이용하여 키보드/마우스 처럼 사용이 가능합니다. 전용 아두이노 키보드나 마우스 제작이 가능한 보드입니다.

키보드/마우스 함수는 32u4 또는 SAMD 마이크로 기반 보드에서 사용되는데 몇개 보드들 중 많이 알려진 보드로는 아두이노 레오나르도, 아두이노 마이크로 보드가 있습니다.


보드가 키보드/마우스를 사용 가능한 보드인지 쉽게 구별하는 방법은 위 사진처럼 Micro USB 모양을 보시고 구별하시면 됩니다.

아두이노 마이크로 보드를 자세히 살펴볼까요.


20개의 디지털 입출력 핀에서 PWM 핀이 7개 있고, 아날로그 입력 핀이 12개나 됩니다. 아두이노우노랑은 차이가 있죠. 자세한 정보는 아두이노 마이크로 데이터시트 한번 읽어주시면 좋겠습니다.

위 그림에서 핀정보만 간단히 아두이노우노와 비교해서 이해하시면 될 듯 싶네요. 어느핀이 무슨핀이고 핀 번호가 어떻게 되는지만 아셔도 충분합니다.

2. 아두이노 마이크로 보드 설정


아두이노 IDE 툴에서는 바로 프로그램을 업로드가 되지 않습니다. 환경 설정을 해 주셔야 하는데 그 방법을 설명 드립니다.

[보드 지정] : Arduino/Genuino Micro로 선택하시오.


[포트 지정] : 아두이노 마이크로를 PC USB에 연결하면 해당 COM숫자(Arduino/Genuino Micro)라고 잡히는데 COM숫자는 랜덤으로 알아서 잡히는데 그 포트를 지정하시면 됩니다.


이 두개의 환경설정이 끝났으면 아두이노 코딩을 한 것을 업로드 시키면 아두이노 마이크로에 프로그램을 이식 시킬 수 있습니다.

3. 아두이노 마이크로 회로도


  • 준비물 : Red LED 1개, 220옴 1개, 아두이노 마이크로
  • 내용 : 12번핀을 Red LED를 제어 하기 위해서 Red LED에 12번 핀을 연결하시오.


4. 코딩



몇 달만에 다시 기초 부분을 거론하게 되었네요. 아두이노우노를 소개했던 기초 실험이였는데 다시 반복하게 되었네요.

[Blink 예제 소스]

const byte redLed = 12;

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

void loop() {
  digitalWrite(redLed, HIGH);  
  delay(1000);                 
  digitalWrite(redLed, LOW);   
  delay(1000);                 
}

1초 단위로 깜박이는 명령인데 위 코딩은 이제 설명 할 필요는 없겠죠.

5. 결과


아래 움짤을 보시는 것과 같이 정상적으로 아두이노 마이크로가 동작하네요.


마무리


오늘은 간단히 아두이노 마이크로 보드에 대해 살펴 보고 정상적으로 동작하는지 실험하는 시간이였습니다. 아두이노 마이크로 보드라고 별도의 코딩이 있는 것은 아닙니다. 단지 환경설정에서 보드/포트 지정만 변경해주시면 됩니다. 이 보도를 통해서 다음에 키보드/마우스 명령을 내려보는 실험을 하도록 하겠습니다.

최근에는 너무 코딩 중심의 복잡한 post가 이루어 졌는데 계속 코딩 중심적 post가 되면 지루 할 것 같아서 새로운 주제로 넘어갔네요. 아두이노 시계에서 4-digit 7-segment display 부품을 74HC595 칩을 결합해서 제어하는 실험까지 post 하고 싶었지만 그 부분은 여러분들에게 상상 숙제로 남겨 둡니다.

댓글()