마음 속 하늘은 항상 맑음~!

아두이노 프로 마이크로를 이용한 USB조이스틱 본문

카테고리 없음

아두이노 프로 마이크로를 이용한 USB조이스틱

파르셀수스 2020. 5. 15. 15:36

 아두이노 프로 마이크로가 USB장치 만느는데 아주 좋다는 이야길 듣고, 아주 예전에 있었던 아날로그 조이패드를 개조했다. 그냥 연결하는데는 방향 컨트롤이 문제가 있어서 방향키 부분을 잘라내고, 그곳에 KY-023 2축 조이스틱 모듈을 붙이고 스위치 1개를 더 얻었다. 사실 다른 옵션이 없어서 그냥 선택한 부품.

 

 아두이노의 조이스틱 라이브러리를 사용해서 코드를 구성했다.

 

 노이즈 같은 중간값에 흔들림이 조금 있어서 흔들림을 무시하도록 조정하기도 했다(NOISE_X, NOISE_Y).

 XCV와 YCV는 중심값으로 127근처로 나온다. USB포트의 약간의 전압드랍으로 125가 나온 듯.

 3.3V로 나중엔 변경해야겠다.

 A0와 A1이 각각 X,Y축이고 버튼들은 0V에 눌러진 상태가 된다.

 

 버튼에 대한 핀번호를 따로 할당할 수 있게 코드를 수정했다.

#include <Joystick.h>
#include <wiring_private.h>


#define MAX_BUTTON 7
//#define DEBUG_XY
#define FASTADC

#define XCV 125
#define YCV 125
#define NOISE_X 4
#define NOISE_Y 4

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK /* JOYSTICK_TYPE_GAMEPAD */,
                   MAX_BUTTON, 0,
                   true, true, false,  // x, y, z axis
                   false, false, false,
                   false, false,
                   false, false, false);

int jbutton[MAX_BUTTON]={5,6,7,8,9,14,16};
int xbv, ybv;
unsigned long sp,ep;

void setup() {
  for (int index = 0; index < MAX_BUTTON; index++) {
    pinMode(jbutton[index], INPUT_PULLUP);    
  }

#ifdef FASTADC
 // set prescale to 16
 sbi(ADCSRA,ADPS2);
 cbi(ADCSRA,ADPS1);
 cbi(ADCSRA,ADPS0);
#endif

  xbv=analogRead(A0) >> 2;  // 127
  ybv=analogRead(A1) >> 2;  // 127
  
  Joystick.begin(); 
  Joystick.setXAxisRange(-127,127);
  Joystick.setYAxisRange(-127,127);
  #ifdef DEBUG_XY
  sp=millis();
  #endif
}

int lastButtonState[MAX_BUTTON] = {0,0,0,0,0,0,0};
int xv, yv;

void loop() {
  xv=(analogRead(A0)>>2);
  xv+=(analogRead(A0)>>2);
  xv>>=1;
  xv-=XCV;
  if(xv<-127) xv=-127;
    else if(xv>127) xv=127;
  if(xv<NOISE_X && xv > -NOISE_X) xv=0;
  
  yv=(analogRead(A1)>>2);
  yv+=(analogRead(A1)>>2);
  yv>>=1;
  yv-=YCV;
  if(yv<-127) yv=-127;
    else if(yv>127) yv=127;
  if(yv<NOISE_Y && yv > -NOISE_Y) yv=0;

  #ifdef DEBUG_XY
  ep=millis();
  if(ep-sp>100) {
    Serial.println(xv);
    Serial.println(yv);
    Serial.println(xbv);
    Serial.println(ybv);
    Serial.println("===");
    sp=ep;
  }
  #endif
    
  Joystick.setXAxis(xv);
  Joystick.setYAxis(yv);

  // Read pin values
  for (int index = 0; index < MAX_BUTTON; index++)
  {
    int currentButtonState = !digitalRead(jbutton[index]);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }
}