디지털 라이프 電子的生活 My Digital Life/아두이노 (Arduino)

플스2 패드를 RC 조종기로 쓰기 - 테스트 회로 및 소스

미친도사 2017. 11. 28. 21:01

플스2를 아두이노 기반의 RC 조종기로 쓰기 지난 이야기.

2017/08/12 - 아두이노 기반 RC의 무선 조종기에 대한 이런저런 생각들...

2017/11/23 - 플스2 패드를 아두이노에 연결하기...


플스2 패드를 아두이노에 연결했으니, 그걸 nRF24L01 모듈을 통해 원격지의 아두이노로 전송하기만 하면 될 겁니다.

또 여기저기 자료를 짜깁기 해서 회로를 구성하고 소스를 수정했습니다.


전에 뭐 만들려고 만능기판에 아두이노랑 nRF24L01 모듈을 붙여놓은 게 있어 그거 활용해서 패드 쪽 회로 구성.


회로 연결은 다음과 같습니다. 전원부는 3.3V를 만들기 위해 레귤레이터 하나 쓴 겁니다.

PS2 connector 쪽 핀배열은 지난 글에도 있지만 아래와 같고, 1번, 8번 핀은 사용하지 않습니다.

1 - 7.5V
2 - GND
3 - VDD (3.3V)
4 - DI
5 - DO
6 - CS
7 - CLK
8 - ACK


패드 쪽 소스는 다음과 같습니다. PS2X 라이브러리와 nRF24L01 라이브러리를 설치해줘야 합니다.

https://github.com/madsci1016/Arduino-PS2X

https://github.com/TMRh20/RF24/archive/master.zip


#include <PS2X_lib.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

// variables for PS2 pad
PS2X ps2x;
int error = 0;
byte type = 0;
byte vibrate = 0;

// variables for nRF24L01
#define CE_PIN 9
#define CSN_PIN 10

const uint64_t pipe = 0xE8E8F0F0E1LL; // communication channel information

RF24 radio(CE_PIN, CSN_PIN);
int valarray[16];

char* functions[]={PSS_LX, PSS_LY, PSS_RX, PSS_RY, PSB_PAD_UP, PSB_PAD_DOWN, PSB_PAD_LEFT, PSB_PAD_RIGHT, PSB_GREEN, PSB_BLUE, PSB_PINK, PSB_RED, PSB_L1, PSB_L2, PSB_R1, PSB_R2};

void setup() {
  radio.begin();
  radio.openWritingPipe(pipe);

// GamePad(CLK, DO, CS, DI, Pressures?, Rumble?)
  error = ps2x.config_gamepad(5,3,4,2, true, true);
  if(error == 0){ } // controller found
  else if(error == 1) { } // no controller found
  else if(error == 2) { }
  else if(error == 3) { }
}

void loop() {
  if(error == 1) return;
  if(type == 2) return;
  else { //DualShock Controller
    ps2x.read_gamepad(false, vibrate);

    // for analog sticks
    for (int i=0; i< 4 ; i++) valarray[i]=ps2x.Analog(functions[i]);

    // for buttons - 1 or 0 is sent
    for (int i=4 ; i <16; i++) {
      if (ps2x.ButtonReleased(functions[i])) valarray[i] = 1; else valarray[i] = 0;
    }

    radio.write(valarray, sizeof(valarray));
  }
}


수신부, 즉 RC카 혹은 RC탱크 쪽 회로가 될 곳은 아래처럼 구성해서 테스트.


테스트용 회로 구성. 서보 하나 달고, LED 4개 달아서 시험해 봅니다.


물론 이와 같이 해서 차가 굴러가는 건 아니지만, 이렇게 통신하는 방법과 받은 데이터의 처리 부분만 이해하면,
다른 부분에 대한 응용은 어렵지 않기 때문에 이 정도로 시험합니다.


수신부 쪽 소스

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>


#define CE_PIN 9

#define CSN_PIN 10


const uint64_t pipe = 0xE8E8F0F0E1LL;


RF24 radio(CE_PIN, CSN_PIN);


int buttons[16];

int LED_ST = 0;


#include <Servo.h>

Servo servo;

int angle = 90;


void setup()

{

  Serial.begin(115200);

  delay(1000);

  Serial.println("Nrf24L01 Receiver Starting");

  radio.begin();

  radio.openReadingPipe(1,pipe);

  radio.startListening();

  delay(5000);

  pinMode(8, OUTPUT);

  pinMode(7, OUTPUT);

  pinMode(6, OUTPUT);

  pinMode(5, OUTPUT);

  pinMode(3, OUTPUT);


  servo.attach(3);

  servo.write(angle);

}


void loop()

{

  if ( radio.available() ) {

    bool done = false;

    while (!done) {

      //done = radio.read( buttons, sizeof(buttons) );

      radio.read( buttons, sizeof(buttons) );

      for (int i=0 ; i< 18; i++){

        Serial.print(buttons[i]);

        Serial.print(" ");

      }      


      if (buttons[3] > 148) {

        angle = angle + 2;

        if (angle > 150 ) angle=150;

      }

      if (buttons[3] < 108) {

        angle = angle - 2;

        if (angle < 30 ) angle=30;

      }

      if (buttons[15] == 1) angle=90;

      Serial.print(angle);

      servo.write(angle);

      digitalWrite(8, buttons[4]);

      digitalWrite(7, buttons[5]);

      digitalWrite(6, buttons[6]);

      digitalWrite(5, buttons[7]);

      delay(15);

      Serial.println("");

    }

  }

  else {

    Serial.println("No radio available");

  }


이걸 업로드하고 아두이노 IDE의 시리얼 모니터 창을 열면, 플스2 패드에서 전송되어 오는 정보를 볼 수 있습니다.

앞에서부터
왼쪽 아날로그 스틱 X , Y 오른쪽 아날로그 스틱 X, Y, 방향 버튼 (상하좌우), 동작버튼 (세모, X, 네모, O), L1, L2, R1, R2 도합 12개와 테스트 용으로 붙여 놓은 서보의 현재 각도를 나타내게 되어 있습니다.

아날로그 스틱은 각 축이 0부터 255까지 변하므로, 모터의 속도 제어로 사용할 수 있을 것 같습니다. 버튼들을 누르면 해당 값이 1로 변하게 되어 있어 그걸로 LED를 켜든지, 어떤 동작에 매핑시켜 사용할 수 있습니다.

이 테스트는 플스2패드에서 수신부로 단방향 통신을 합니다. 만약 RC카/탱크로부터 뭔가 정보를 패드쪽 아두이노로 받아야 한다면 좀 복잡해지겠더군요. 일단, 패드로 RC카/탱크 조종하는 건 이 정도 소스만으로 충분할 겁니다.


좀 아쉬운 점은 실제 플스2 패드에서는 L3, R3 및 SELECT / START 버튼까지 있는데, RF2.4 아두이노 라이브러리가 전달할 수 있는 배열(array)의 크기가 16까지로 제한되는 것 같습니다. 그래서 지금 라이브러리 제작자에게 문의 메일을 보내놨습니다만, 답이 올지는 모르겠네요.

이런 제약이 있다 하더라도 요 상태만으로도 아날로그 스틱 4채널 + 디지털 버튼 12개라는 꽤 많은 정보를 전달할 수 있습니다. 해외 사용자들 글을 보면 단가 1000원 쯤하는 RF 모듈로 대략 30m 정도 커버하는 것 같다하니 (실제로 얼마나 먼 거리까지 되는지는 나중에 더 확인해 봐야겠지만) 실내에서 갖고 노는 수준의 RC카 혹은 RC탱크 용도로는 충분할 것 같습니다. 외장 안테나가 있는 모듈의 경우 스펙상으론 1.1km까지 가능하다고 하니 더 넓은 곳까지도 해볼만 하지 않겠나 싶습니다.


너무 복잡하다 싶고 7-8m 이내의 환경이라면, 지난 이야기에서 언급한 무선 패드로 해도 좋을 것 같습니다.

이제 실제 모형에 넣고 구현하는 일만 남은 것 같습니다.

반응형