본문 바로가기

카테고리 없음

아두이노 우노 R4 조이스틱 다루기

반응형

 

 

이 가이드에서는 Arduino UNO R4에서 조이스틱을 사용하는 방법을 알아봅니다. 여기서 다루 것은 아래 사항입니다.

 

  • 조이스틱 작동 방식
  • Arduino UNO R4에 조이스틱을 연결하는 방법
  • 조이스틱에서 값을 읽도록 Arduino UNO R4를 프로그래밍하는 방법
  • 조이스틱에서 읽은 값을 실행 가능한 값(예: 모터의 XY 좌표 또는 방향)으로 변환하는 방법 

 

엄지 조이스틱이라는 단어를 들으면 가장 먼저 떠오르는 것은 게임 컨트롤러입니다. 주로 게임 플레이에 사용되지만, DIY 전자 제품에서는 엄지 조이스틱으로 할 수 있는 재미있는 일이 많이 있습니다. 로봇/로버를 제어하거나 카메라의 움직임을 제어하는 것 등은 빙산의 일각에 불과합니다. 

 

 

하드웨어 개요

 

PS2(플레이스테이션 2) 컨트롤러의 '아날로그' 조이스틱과 매우 유사한 조이스틱입니다. 셀프 센터링 스프링이 장착된 조이스틱으로, 조이스틱에서 손을 떼면 자동으로 중심이 잡힙니다. 또한 편안한 컵형 노브/캡이 있어 엄지손가락의 느낌을 줍니다.

 

 

 

조이스틱의 목표는 2D(2축)로 동작을 아두이노에 전달하는 것입니다. 이를 위해 두 개의 독립적인 10K 포텐셔미터(축당 하나씩)가 장착되어 있습니다. 이 포텐셔미터는 조정 가능한 이중 전압 분배기로 사용되어 2축 아날로그 입력을 컨트롤 스틱 형태로 제공합니다.

 

포텐셔미터는 조이스틱 측면에 있는 두 개의 파란색 상자입니다. 각 포텐셔미터의 중앙 축을 보면서 조이스틱을 움직이면 각 포텐셔미터가 한 방향으로만 움직임을 감지하는 것을 볼 수 있습니다. 실제로 어떻게 작동하는지 잠시 후에 설명하겠습니다. 

 

 

 

이 조이스틱에는 캡을 아래로 누르면 활성화되는 스위치도 포함되어 있습니다. 스위치는 조이스틱 뒷면에 있는 작은 블랙박스입니다. 캡을 아래로 누르면 스위치 머리 부분을 아래로 누르는 레버가 보입니다. 레버는 조이스틱이 어떤 위치에 있든 상관없이 작동합니다.

 

PS2 2축 엄지 조이스틱 모듈의 작동 원리

 

조이스틱의 기본 개념은 X축(왼쪽에서 오른쪽)과 Y축(위아래)의 두 축에서 스틱의 위치를 아두이노가 처리할 수 있는 전자 정보로 변환하는 것입니다. 이는 약간 까다로울 수 있지만 두 개의 포텐셔미터와 짐벌 메커니즘으로 구성된 조이스틱의 설계 덕분에 가능합니다. 짐벌 메커니즘 

 

짐벌 메카니즘

 

조이스틱을 돌리면 엄지손가락 핸들이 두 개의 회전 가능한 슬롯형 샤프트(짐벌)에 장착된 좁은 막대를 움직입니다. 샤프트 중 하나는 X축(왼쪽 및 오른쪽)으로 움직이고 다른 하나는 Y축(위아래)으로 움직일 수 있습니다. 스틱을 앞뒤로 기울이면 Y축 샤프트가 좌우로 피벗됩니다. 스틱을 왼쪽에서 오른쪽으로 기울이면 X축 샤프트가 회전합니다. 스틱을 대각선으로 움직이면 양쪽 축이 모두 회전합니다. 

 

 

 

 

각 조이스틱 샤프트에는 막대의 위치를 아날로그 판독값으로 해석하는 포텐셔미터가 연결되어 있습니다. 슬롯형 샤프트를 움직이면 포텐셔미터의 접촉 암이 회전합니다. 즉, 스틱을 앞으로 끝까지 밀면 전위차계 접점 암이 트랙의 한쪽 끝으로 돌아가고, 다시 사용자 쪽으로 당기면 접점 암이 반대 방향으로 돌아갑니다.

 

조이스틱에서 아날로그 값 읽기

 

조이스틱의 물리적 위치를 읽으려면 전위차계의 저항 변화를 측정해야 합니다. 이 변화는 ADC를 사용하는 아두이노 아날로그 핀으로 읽을 수 있습니다.

 

아두이노 보드의 ADC 분해능은 10비트이므로 각 아날로그 채널(축)의 값은 0에서 1023까지 다양할 수 있습니다. 따라서 X축에서 스틱을 한쪽 끝에서 다른 쪽 끝으로 이동하면 X값이 0에서 1023까지 변하고 Y축을 따라 이동할 때도 비슷한 일이 일어납니다. 조이스틱이 중앙 위치에 있을 때 값은 약 512입니다.

 

아래 그래픽은 X 및 Y 방향을 보여주며, 조이스틱을 다양한 방향으로 밀었을 때 출력이 어떻게 반응하는지도 보여줍니다. 

 

 

엄지 조이스틱 모듈 핀아웃

 

PS2 2축 엄지 조이스틱 모듈의 핀아웃을 살펴보겠습니다. 

 

 

 

  • GND는 아두이노의 GND 핀을 연결하는 접지 핀입니다.
  • VCC는 모듈에 전원을 공급합니다. 아두이노의 5V 출력에 연결할 수 있습니다.
  • VRx는 조이스틱의 수평 방향(X-좌표), 즉 조이스틱을 좌우로 얼마나 밀었는지 판독합니다.
  • VRy는 조이스틱의 수직 방향(Y좌표), 즉 조이스틱을 위아래로 얼마나 밀었는지 판독합니다.
  • SW는 푸시 버튼의 출력입니다. 일반적으로 개방 상태이므로 SW 핀의 디지털 판독값은 HIGH가 됩니다. 버튼을 누르면 GND에 연결되어 출력이 LOW가 됩니다. 

연결도를 참고하세요.

 

 

 

 

가장 단순한 동작코드는 아래와 같습니다.

 

int xValue = 0 ;
int yValue = 0 ; 
int bValue = 0 ;

void setup()	
{	
	Serial.begin(9600) ;
	pinMode(8,INPUT); 
	digitalWrite(8,HIGH);	
}	

void loop()	
{	
	xValue = analogRead(A0);	
	yValue = analogRead(A1);	
	bValue = digitalRead(8);	
	Serial.print(xValue,DEC);
	Serial.print(",");
	Serial.print(yValue,DEC);
	Serial.print(",");
	Serial.print(!bValue);
	Serial.print("\n");
	delay(10);	
}

 

 

아날로그 값을 읽는 우노 R4 코드

 

/*
 * This Arduino UNO R4 code was developed by newbiely.com
 *
 * This Arduino UNO R4 code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-joystick
 */

#define VRX_PIN  A0 // The Arduino UNO R4 pin connected to VRX pin
#define VRY_PIN  A1 // The Arduino UNO R4 pin connected to VRY pin

int xValue = 0; // To store value of the X axis
int yValue = 0; // To store value of the Y axis

void setup() {
  Serial.begin(9600) ;
}

void loop() {
  // read analog X and Y analog values
  xValue = analogRead(VRX_PIN);
  yValue = analogRead(VRY_PIN);

  // print data to Serial Monitor on Arduino IDE
  Serial.print("x = ");
  Serial.print(xValue);
  Serial.print(", y = ");
  Serial.println(yValue);
  delay(200);
}

 

 

ezButton 라이브러리를 설치하고 아날로그 값과 버튼의 상태를 읽는 코드 

 

우선 ezButton 라이브러리를 아래와 같이 검색하여 설치하세요..

 

 

/*
 * This Arduino UNO R4 code was developed by newbiely.com
 *
 * This Arduino UNO R4 code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-joystick
 */

#include <ezButton.h>

#define VRX_PIN  A0 // The Arduino UNO R4 pin connected to VRX pin
#define VRY_PIN  A1 // The Arduino UNO R4 pin connected to VRY pin
#define SW_PIN   2  // The Arduino UNO R4 pin connected to SW  pin

ezButton button(SW_PIN);

int xValue = 0; // To store value of the X axis
int yValue = 0; // To store value of the Y axis
int bValue = 0; // To store value of the button

void setup() {
  Serial.begin(9600) ;
  button.setDebounceTime(50); // set debounce time to 50 milliseconds
}

void loop() {
  button.loop(); // MUST call the loop() function first

  // read analog X and Y analog values
  xValue = analogRead(VRX_PIN);
  yValue = analogRead(VRY_PIN);

  // Read the button value
  bValue = button.getState();

  if (button.isPressed()) {
    Serial.println("The button is pressed");
    // TODO do something here
  }

  if (button.isReleased()) {
    Serial.println("The button is released");
    // TODO do something here
  }

  // print data to Serial Monitor on Arduino IDE
  Serial.print("x = ");
  Serial.print(xValue);
  Serial.print(", y = ");
  Serial.print(yValue);
  Serial.print(" : button = ");
  Serial.println(bValue);
}

 

 

다음은 아날로그 값을 읽고 네 방향으로 움직임을 표시하는 코드입니다.

 

/*
 * This Arduino UNO R4 code was developed by newbiely.com
 *
 * This Arduino UNO R4 code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-joystick
 */

#define VRX_PIN  A0 // The Arduino UNO R4 pin connected to VRX pin
#define VRY_PIN  A1 // The Arduino UNO R4 pin connected to VRY pin

#define LEFT_THRESHOLD  400
#define RIGHT_THRESHOLD 800
#define UP_THRESHOLD    400
#define DOWN_THRESHOLD  800

#define COMMAND_NO     0x00
#define COMMAND_LEFT   0x01
#define COMMAND_RIGHT  0x02
#define COMMAND_UP     0x04
#define COMMAND_DOWN   0x08

int xValue = 0 ; // To store value of the X axis
int yValue = 0 ; // To store value of the Y axis
int command = COMMAND_NO;

void setup() {
  Serial.begin(9600) ;
}

void loop() {
  // read analog X and Y analog values
  xValue = analogRead(VRX_PIN);
  yValue = analogRead(VRY_PIN);

  // converts the analog value to commands
  // reset commands
  command = COMMAND_NO;

  // check left/right commands
  if (xValue < LEFT_THRESHOLD)
    command = command | COMMAND_LEFT;
  else if (xValue > RIGHT_THRESHOLD)
    command = command | COMMAND_RIGHT;

  // check up/down commands
  if (yValue < UP_THRESHOLD)
    command = command | COMMAND_UP;
  else if (yValue > DOWN_THRESHOLD)
    command = command | COMMAND_DOWN;

  // NOTE: AT A TIME, THERE MAY BE NO COMMAND, ONE COMMAND OR TWO COMMANDS

  // print command to serial and process command
  if (command & COMMAND_LEFT) {
    Serial.println("COMMAND LEFT");
    // TODO: add your task here
  }

  if (command & COMMAND_RIGHT) {
    Serial.println("COMMAND RIGHT");
    // TODO: add your task here
  }

  if (command & COMMAND_UP) {
    Serial.println("COMMAND UP");
    // TODO: add your task here
  }

  if (command & COMMAND_DOWN) {
    Serial.println("COMMAND DOWN");
    // TODO: add your task here
  }
}

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^