조이스틱마우스에 해당하는 글 1

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

IOT/아두이노|2019. 7. 2. 09:00

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



지난 시간에 아두이노 마우스 제어를 스위치버턴으로 실험해 보았습니다. 스위치 버턴의 경우는 위/아래, 좌/우, 대각선 방향으로 선형 이동을 하게 됩니다. 곡선 이동은 스위치버턴으로 표현하기가 힘듭니다. 실제 마우스의 움직임을 보면 원형 방향을 회전을 하면 약간 곡선 모양으로 움직이는데 스위치버턴으로는 그 표현이 어렵습니다. 그래서, 좀 더 부르겁게 움직이게 하기 위해서 조이스틱을 이용하여 실험을 해보겠습니다. 아두이노 IDE의 USB 예제 중 "JoystickMouseControl"소스를 기반으로 실험을 하겠습니다.

조이스틱에는 xAxis, yAxis 값과 swPin(스위치버턴) 값을 출력합니다. 조이스틱의 x,y과 스위치버턴 이벤트만 적용하여 실험이 이루어집니다. 아래 사진의 3개의 파란버턴을 있는데 한개 버턴만 인터럽트스위치버턴으로 마우스 동작을 수행할 것인지 안할 것인지 결정하는 안정장치 버턴으로 활용합니다. 사실 스위치 버턴을 사진에 들어가 있지만 표현할 필요는 없습니다. 조이스틱이 버턴 한개가 내장 되어있으니깐 원래는 스위치 버턴이 필요 업습니다.


아두이노 마이크로에서 조이스틱을 제어해 볼까요.

1. 조이스틱 마우스 사전학습



조이스틱 마우스 예제인 "JoystickMouseControl" 설명이 잘 나와 있습니다. 사실 조이스틱으로 직접 제어하는 코딩을 만들어 보긴 했는데 위 사전학습의 예제가 너무 완벽해서 제가 만든 방식을 포기하게 되었네요.

[조이스틱 핵심 코딩] - 출처 : https://www.arduino.cc/en/Tutorial/JoystickMouseControl (코딩 일부분)

int readAxis(int Axis_Val) { 
  int reading = analogRead(Axis_Val); //해당 축핀의 아날로그 값을 읽음
  reading = map(reading, 0, 1023, 0, 12); //읽은 아날로그 신호를 0~12 사이의 값으로 변환
  int distance = reading - 6; //축값은 0~12인데 중심값이 6을 기준으로 +방향과 -방향값을 갖음
  if (abs(distance) < 3) { //+방향, -방향값이 3이하면 마우스 이동을 안하기 위해 0으로 초기화
    distance = 0;
  }
  return distance; //해당 축의 마우스 이동값을 반환
}

위 코딩에서 조이스틱이 특정 축(Axis_Val)의 기준으로 이동할 경우 0~1023일때 0~12값으로 변환하면 조이스틱의 움직임 값은 중심은 512가 6이 됩니다. 6을 기준으로 +방향과 -방향으로 나뉘게 됩니다. 중심값 6을 기준으로 얼마만큼 조이스틱이 움직였는가에 따라서 그 움직임을 마우스를 움직이게 합니다. 이때 움직임 값이 3이상 조이스틱이 움직여야지 움직임으로 인정을 하게 됩니다.

아래의 그림에서 노란색 원 모양의 영역이 조이스틱의 움직임을 불인정 구간이 됩니다. 조이스틱의 움직임을 인정하는 영역이 초록색이 됩니다.


왜! 이러헥 튜토리얼 예제에서는 표현했을까요. 실제 조이스틱은 전류를 측정하면 정확히 중심축(x,y)이 (512,512)가 되지 않습니다. 그래서 오차 중심축 값이 발생합니다. 그래서 오차의 영역이 되는 위의 원 영역의 부분은 움직임으로 판정을 내리지 않게 되면 오차값에 의한 움직임이 발생하지 않습니다. 그리고 튜토리얼에서는 0~12로 숫자의 범위를 최대한 줄였고 움직임 판정 받을 수 있는 영역도 6에서 3인 불인정이기 때문에 나머지 3의 영역만 인정을 받게 됩니다. 즉, 조이스틱의 크게 움직여야만 그 움직임을 인정받을 수 있게 됩니다. 각 1의 영역도 아날로그 신호값을 기준으로 85.25정도의 신호값을 1로 하기 때문에 오차가 발생하더라고 그렇게 크게 조이스틱 움직이에 영향을 주지 않습니다.

위 공식홈페이지에서 조이스틱 조정으로 측정되는 x,y축 값은 이보다 훌륭한 코딩은 없다고 생각되네요. 제가 만들어서 실험한 코딩은 위와 좀 비슷하지만 위 튜토리얼 코딩이 너무 훌륭해서 위 함수을 인용해서 실험하게 되었습니다.

2. 아두이노 조이스틱 마우스 회로도


  • 준비물 : 조이스틱 1개, 스위치버턴 1개, LED 1개, 저항 220옴 1개, 아두이노 마이크로
  • 내용 : 조이스틱 xAxis, yAxis축은 A0, A1 핀에 연결하고 swPin은 3번에 연결하시오. 인터럽트스위치버턴은 2번에 연결하고 LED 4번에 연결하면 됩니다.


조금 선 연결이 복잡해 보일 수 있는데 위의 내용부분의 핀 연결만 제대로 하시면 나머지 Vcc, Gnd 핀이기 때문에 어렵지 않을꺼에요.

3. 코딩



위 사이트에 가시면 "JoystickMouseControl" 예제에 대해서 설명이 나와 있습니다. 한번 읽어주시기 바랍니다.

[JoystickMouseControl 소스 인용] - 출처 : https://www.arduino.cc/en/Tutorial/JoystickMouseControl (아두이노공식홈페이지)

#include <Mouse.h>

const byte interruptPin = 2;
boolean state = true;

const byte xAxis = A0;         //X axis
const byte yAxis = A1;         //Y axis
const byte mouseButton = 3;  //LEFT BUTTON
const int ledPin = 4;         // Mouse control LED 

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(mouseButton, INPUT_PULLUP);       
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);  //인터럽트 발생 시 호출
  
  Mouse.begin();
}

void loop() {
  
  if(state==false){ //인터럽트스위치 버턴에 의해서 열림/닫힘
    int Axis_X = readAxis(xAxis); //x축 조이스틱 이동값
    int Axis_Y = readAxis(yAxis); //y축 조이스틱 이동값
        
    Mouse.move(Axis_X, Axis_Y, 0); //마우스 이동

    if (digitalRead(mouseButton) == LOW) { //마우스 스위치가 눌러졌는가
      if (!Mouse.isPressed(MOUSE_LEFT)) Mouse.press(MOUSE_LEFT);      
    }
    else if(Mouse.isPressed(MOUSE_LEFT) == 1){ //MOUSE_LEFT 상태인지 확인
        Mouse.release(MOUSE_LEFT);
    }
    delay(10);
  }
  
}

int readAxis(int Axis_Val) { 
  int reading = analogRead(Axis_Val); //해당 축핀의 아날로그 값을 읽음
  reading = map(reading, 0, 1023, 0, 12); //읽은 아날로그 신호를 0~12 사이의 값으로 변환
  int distance = reading - 6; //축값은 0~12인데 중심값이 6을 기준으로 +방향과 -방향값을 갖음
  if (abs(distance) < 3) { //+방향, -방향값이 3이하면 마우스 이동을 안하기 위해 0으로 초기화
    distance = 0;
  }
  return distance; //해당 축의 마우스 이동값을 반환
}

void exchange() { //인터럽트스위치버턴  이벤트
 state=!state;
 digitalWrite(ledPin, !state);
}

위 소스는 "JoystickMouseControl" 예제를 기반의 코딩입니다. 제가 코딩한 것이 아니라 아두이노 공식홈페이지의 소스를 기반으로 했기 때문에 인용 코딩으로 보시면 됩니다. 인용 부분은 readAxis(int Axis_Val) 함수입니다.

4. 결과


우선 웹문서에 켄버스에 영역을 지정하고 그 영역에 마우스가 움직여서 특정 위치를 마우스 왼쪽버턴을 클릭하게 클릭된 위치에 마우스 좌표를 출력하는 html를 만들었습니다. 자바스크립트로 만들었는데 이건 여러분들이 만드실 필요 없습니다. 동영상 촬영을 위한 체크용으로 간단히 만들어서 조이스틱 마우스를 움직임과 클릭 이벤트가 정상적으로 수행되는지 보기 위한 예제입니다.

그리고, 영상을 보시면 처음에 파란스위치 버턴을 클릭하면 초록색 불이 들어오는 것을 보실 수 있을 꺼에요. 인터럽트 스위치 버턴을 클릭 했을 때 초록색 LED에 불이 들어오고 이 상태는 조이스틱마우스를 제어할 수 있는 열림상태가 된다는 의미이고 초록색 불이 꺼져있으면 조이스틱마우스가 아무리 움직여도 PC 모니터에 움직임이 표시되지 않는 잠금상태가 된다고 생각하시면 됩니다.


화살표로 표시된 스위치버턴(인터럽트스위치)은 조이스틱마우스 사용을 제어하는 안정장치 버턴입니다. 열림/닫힘으로 조이스틱마우스를 사용을 결정하게 됩니다.

마우스 이동과 클릭 이벤트가 정상적으로 수행되는 것을 아래 동영상으로 확인하실 수 있을 꺼에요


마무리


제가 직접 자작한 코딩으로 보여주면 좋은데 튜토리얼 조이스틱 움직임 readAxis()함수 너무 훌륭해서 인용한 실험이 되고 말았네요. 키보드 였다면 간단히 직선적 움직임으로 제어하면 코딩이 쉽지만 마우스를 제어하기 때문에 곡선적 움직임을 제어하기 위해서는 인용한 저 함수가 딱인 것 같네요

아무튼 해당 예제를 기반으로 실험을 했지만 조이스틱마우스의 조정과 클릭 이벤트가 정상적으로 결과를 얻을 수 있었네요. 다음 실험을 조이스틱키보드로 해서 특정 게임을 직접 조정하는 실험을 해볼까 생각중이네요. 아직 어떤 게임을 아두이노 조이스틱으로 조정할지는 결정을 못했고 며칠 일이 생겨서 잠시 post 며칠 미루어 질 것 같네요.


댓글()