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

IOT/아두이노|2019. 4. 19. 09:00

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



최근 포스팅 내용이 너무 코딩에 치우친 것 같아서 오늘은 가벼운 마음으로 간단히 실험 할 수 있는 주제로 꾸몄습니다. 가상시뮬레이터에서 제공하지 않지만 설명만으로 대충 이해 할 수 있는 부품이여서 부담 없이 읽으시면 됩니다. 오늘 다룰 주제는 조이스틱으로 꽤 재밌는 모듈입니다. 방향을 조정 할 수 있는 모듈로서 RC카와 같은 뭔가 조정이 필요한 곳에 사용되는 모듈입니다. 아두이노마이크로나 레오라르도보드가 있다면 컴퓨터 마우스를 만들고 싶은 부품입니다. 아무튼 조이스틱의 구조는 복잡하지 않습니다. 조이스틱 모듈에서 만들어내는 신호는 방향을 표현하는 아날로그 신호와 스위치를 표현하는 디지털 신호가 있습니다. 이 둘 신호에 대해 읽기를 할 수 있다면 쉽게 제어가 가능한 부품입니다. 간단한 실험으로 어떻게 동작하는지 살펴보도록 하겠습니다.

1. 조이스틱의 구조

위 사진에서 자세히 보면 Gnd, +5V, VRX, VRY, SW 이렇게 5개의 핀으로 구성되 있습니다. Gnd, +5V은 전원부분에 해당되고 나머지 3개의 핀에서 VRX, VRY은 아날로그 출력핀으로 방향좌표(x,y) 아날로그 신호를 만들어 내고 SW은 디지털 출력핀으로 스위치 버턴 역할로 디지털 신호를 만들어 냅니다. 참고로 위 사진에서 스위치는 방향 조정기의 몸통을 누르거나 옆에 스위치 버턴이 있습니다.

방향(x,y)과 스위치 한개를 누를 수 있는 모듈이구나 정도로 이해하시면 됩니다.

그러면 조이스틱의 방향키를 움직였을 때 아날로그 신호는 어떻게 변하는지 살펴보도록 할까요.

X, Y 좌표를 나눠서 생각하시면 됩니다. 위 그림처럼 가운데 동그라미가 조이스틱 중심 지점이라고 생각 하십시오, 그리고 조이스틱이 그 중심에서 오른쪽, 왼쪽, 위, 아래 그리고 각 대각선으로 나눠서 구분하시면 됩니다.

그러면 간단히 살펴볼까요.

아날로그 신호는 X축으로 0~1023의 값을 읽을 수 있습니다. 그 중심값 512가 됩니다.
아날로그 신호는 Y축으로 0~1023의 값을 읽을 수 있습니다. 그 중심값 512가 됩니다.

그러면 방향조정기를 조절하고 그 신호값을 만들어 낼려할 때 여러분들이 조이스틱 설계자라면 아날로그 신호에서 어디를 기준으로 설계 할 까요. 바로 중심값을 기준으로 잡겠죠. 아날로그 신호가 0~1023값이 고정되어 있으니 X축을 기준으로 좌우의 방향을 나눌려면 어느 위치를 중심으로 해야 할까요. 바로 신호값 512가 되겠죠. 아날로그 신호 512 위치가 중심이 되면 좌측은 X신호값이 0~512사이의 값이 되고 우측은 512~1023사이의 값이 되겠죠. 이 값을 기준으로 좌측과 우측의 이동 신호값으로 표현하면 됩니다. Y축도 이와 같습니다.

처음에 핀을 아두이노에 연결하면 읽은 신호값이 초보분들은 정확히 뭘 의미하는지 이해를 잘 못하지만 위 그림처럼 그림을 그리고 나서 가운데 원이 방향조정기로 움직인다고 상상하면서 좌표를 이해하시면 됩니다.

방향 좌표 수치를 이해가 되셨다면, 중심(X,Y) = (512,512)을 기준으로 신호값이 실제 조정기를 해당 방향으로 움직이면 어떻게 변하는지 이해 하실 수 있을 거라 생각됩니다.

주의사항

현실에서는 중심점(512,512) 값을 가지지 못합니다. 그 이유는 조이스틱이 기계이고 조립과정 또는 환경 요인에 의해서 중심값은 (512,512)가 나오지 않습니다. 같은 모듈이여도 제각각으로 중심값 신호가 나옵니다. 실제 측정한 조이스틱 중심값을 다시 선을 뽑았다 다시 연결하니깐 약간의 수치가 살짜 1정도 다른 값이 나오기도 하더군요. 그래서 초기 기준값을 정하는 보정 작업이 필요 합니다. 오늘은 코딩적인 부분을 다루는 것이 목적이 아니고 간단히 조이스틱이 어떻게 생겼으며 어떻게 값을 읽을지를 알아보는 실험이니깐 코딩에 대해서 깊게 안들어가고 간단히 이해만 해주세요.

만약, 보정작업을 수행하고 싶으시다면 중심값 관련 보정 작업은 중심값의 환경적 요인에 의해 차이가 나니깐 일정 값의 범위를 지정해서 그 값 안에 있으면 중심으로 간주하는 방법으로 보정해 주는게 가장 간단한 보정 할 수 있는 방법이라고 생각 됩니다.

인터넷에서 조이스틱 실험 예제들을 살펴보시면 정확한 수치로 쪼개서 나누지 않고 방향의 범위값을 허용하는 일정 범위를 지정해 놓고 그 범위에 들어오면 방향을 움직이는 걸로 판정을 내리더군요. 그게 가장 간단하면서 문제를 쉽게 해결할 수 있는 방법이라고 저도 생각 되네요.

아무튼 실제로 테스트 한 결과값은 아래 실험에서 자세히 나와 있으니깐 제가 쓰는 조이스틱의 중심값이 어떻게 나왔는지 아래 포스팅 내용을 보시기 바랍니다.

2. 회로도


  • 준비물 : 조이스틱 1개, 아두이노우노
  • 내용 : A0, A1 핀은 x,y 방향 아날로그 신호를 받고 5번핀은 스위치 신호를 받도록 선은 연결 하시오.


[ Fritzing 디자인 ]

조이스틱은 아날로그 핀 2개랑 디지털 핀 1개를 아두이노에서 여러분들이 원하는 핀을 선택하여 연결하시면 됩니다. 따로 복잡한 부분은 없습니다.. 실제로 조이스틱을 구매 안하셔도 이런 부품이 있고 대충 연결은 어떤식으로 이루어지는지만 위 그림을 보시면 됩니다. 조이스틱 모듈에 핀 이름이 다 적혀 있으니깐 위 그림을 안보더라도 쉽게 선을 연결 할 수 있을 거라 생각됩니다.

3. 코딩


  • 사용함수 : pinMode(), analogRead(), digitalRead(), delay(), Serial.begin(), Serial.println()
  • 내용 : 시리얼모니터로 조이스틱 값을 출력하자.

함수

  • pinMode(사용핀, 입/출력모드) : 해당 사용핀을 어떤 모드로 사용할지 결정한다. INPUT_PULLUP모드로 설정(내부저항을 사용할 예정)
  • analogRead(아날로그핀) : 아날로그 신호를 읽음(0~1023)
  • digitalRead(디지털핀) : 디지털 신호를 읽음(0 or 1)
  • delay(시간값) : 시간값만큼 대기한다.

통신

  • Serial.begin(9600) : 시리얼통신 시작
  • Serial.println(값) : 시리얼모니터로 값을 출력함.

[ 소스 ] : 제 블로그에 있던 소스를 가져옴.(수정하기 귀찮아서요)

const int AXIS_X = A0;
const int AXIS_Y = A1;
const int SW_P = 2; 
 
void setup() {
  Serial.begin(9600);
  pinMode(SW_P,INPUT_PULLUP);
}
 
void loop() {

  Serial.print("Axis_X: ");
  Serial.println(analogRead(AXIS_X));

  Serial.print("Axis_Y: ");
  Serial.println(analogRead(AXIS_Y));

  Serial.print("SW_P:  ");
  Serial.println(digitalRead(SW_P));

  delay(500);
}

방향 x, y 값은 아날로그 신호값 => analogRead(AXIS_X), analogRead(AXIS_Y)
스위치 값은 디지털 신호 값 =>digitalRead(SW_P)

참고로 내부풀업저항을 사용하기 때문에 스위치버턴의 초기 값은 1이 됩니다. 스위치를 누르면 디지털 신호는 0이 됩니다.

내부풀업저항이 기억이 안나면 다시 복습해야 겠죠. =>[아두이노] 스위치 버턴 제어

4. 결과


위 사진을 보면 조이스틱의 오차값이 발생합니다. 정확하게 중앙값이 생성되지 않습니다. 조이스틱을 만지지 않을 때 정중앙에 위치하는데 그 값이 X=499이고 Y=529가 표시 되네요. 중앙이니깐 X=512, Y=512 이라고 생각하시면 절대 안돼요. 아날로그 값을 읽을 때는 처음 읽을 때 자신이 생각하는 값이 나오지 않습니다. 그래서 초기 측정값을 기준으로 처음 보정 작업이 필요 합니다. 기준값을 우선 찾은 후 그 기준값으로 아두이노에서 어떻게 제어 할지를 정해야 합니다. 그리고 조이스틱은 같은 제품이여도 X, Y값은 약간씩 차이가 납니다. 그렇기 때문에 이 포스트 보고 포스트에 나온 값에 맞춰서 로직을 짜야지 하면 안되고 우선 자기가 사용하는 부품의 초기값이 몇인지를 체크하시고 나서 로직을 짜셔야 합니다.

마무리


조이스틱을 다루는데 어렵지 않죠. 해당 핀에 아날로그 신호랑 디지털 신호만 읽어오면 됩니다. 여기서, 조이스틱을 움직 일 때 그 움직임에 맞춰서 LED에 불이 들어오게 설계를 했는데 동일한 응용 예제를 누가 이미 다른 블로그에 시연을 해버려서 코드로직도 90% 이상 응용코드가 일치해서 실험은 했는데 포스트에 올리지를 못하게 되었네요. 기본 동작 소스는 90%이상 일치하더라도 이건 어쩔 수 없는 부분이지만 응용편이 90% 일치한 내용이 있다면 사실 올리기 좀 껄꺼롭기 때문에 실험은 했고 영상은 있는데 그냥 포기 했네요.

말로만 설명하자면 X축을 기준으로 if문으로 512을 중앙으로 가정하고 512이하면 0~512 사이면 왼쪽 LED에 불이 들어오고 아니면 512이상이면 512~1023 사이면 오른쪽 LED에 불이 들어오게 하고 Y축은 이와 동일하게 IF 조건문을 세우면 방향에 따른 LED에 불이 들어 오겠죠. 그리고 스위치 부분은 스위치가 눌러지면 LED 하나를 스위치 담당 LED로 해서 해당 LED에 불이 들어오게 표시하면 간단히 조이스틱을 조정하여 시각적으로 LED로 표현할 수 있었는데 너무 동일한 응용 예제라서 만들어 놓고 포스트에는 올릴 수 없었네요.

마지막으로, 가상시뮬레이터에서 제공되지 않는 부품 모듈이지만 한번 조이스틱으로 여러분들은 뭘 만들고 싶은지 상상만 해보셨으면 해요. 다른거로 표현 할 만한게 떠오르면 응용 예제로 올려 보도록 할께요. LED 응용 회로로 다 만들었는데 그냥 분해 했네요.


댓글()