简体   繁体   English

蓝牙Arduino游戏手柄

[英]Bluetooth Arduino Gamepad

I am trying to make a custom Bluetooth controller with 2 analog sticks and 16 buttons using an RN-42XV Bluetooth chip and an arduino that I can use with an android and my windows pc. 我正在尝试使用RN-42XV蓝牙芯片和arduino制作具有2个模拟摇杆和16个按钮的自定义蓝牙控制器,可以与android和Windows pc一起使用。 So far I have successfully coded the the arduino leonardo to work as a game-pad with 2 analog sticks and 16 buttons, but I have been unable to get the arduino to work with my RN-42XV bluetooth. 到目前为止,我已经成功地将arduino leonardo编码为具有2个模拟摇杆和16个按钮的游戏手柄,但是我无法使arduino与我的RN-42XV蓝牙一起工作。 The RN-42XV connects to my pc and shows up as a gamepad with 2 analog sticks and 16 buttons, but when I press buttons on the arduino, it does not register with the RN-42. RN-42XV连接到我的电脑,并显示为带有2个模拟摇杆和16个按钮的游戏手柄,但是当我按下arduino上的按钮时,它不会向RN-42注册。 The code that I am using is bellow, please help. 我使用的代码如下,请提供帮助。

#include "Joystick2.h"
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#define BLUETOOTH_SERIAL_RATE 9600

//Buttons defined according to https://www.w3.org/TR/gamepad/
#define BUTTON_0        0
#define BUTTON_1        1
#define BUTTON_2        2
#define BUTTON_3        3
#define SHOULDER_LEFT   4
#define SHOULDER_RIGHT  5
#define TRIGGER_LEFT    6
#define TRIGGER_RIGHT   7
#define START           8
#define SELECT          9
#define THUMB_LEFT      10
#define THUMB_RIGHT     11
#define HAT_UP          12
#define HAT_DOWN        13
#define HAT_LEFT        14
#define HAT_RIGHT       15
#define HOME            16

#define x1   A1
#define y1  A0
#define x2      A3 // Pin 20
#define y2      A2 // Pin 19



void setup() {

Serial.begin(BLUETOOTH_SERIAL_RATE);
  delay(500);
  // Initialize Button Pins - comment out  any unused
//   pinMode(0, INPUT_PULLUP); 
//   pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
//   pinMode(14, INPUT_PULLUP);
//   pinMode(15, INPUT_PULLUP);
//   pinMode(16, INPUT_PULLUP);
//   pinMode(18, INPUT_PULLUP);
//   pinMode(19, INPUT_PULLUP);
//   pinMode(20, INPUT_PULLUP);
//   pinMode(21, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick[0].begin();

  Joystick[1].begin();

}

//Edit button to pin mapping according to your hardware - use -1 if unused
int pinToButtonMap[20][2] =  {{BUTTON_0,        9},
                              {BUTTON_1,        8},
                              {BUTTON_2,        7},
                              {BUTTON_3,        6},
                              {SHOULDER_LEFT,   4},
                              {SHOULDER_RIGHT,  5},
                              {TRIGGER_LEFT,    -1},
                              {TRIGGER_RIGHT,   -1},
                              {START,           3},
                              {SELECT,          2},
                              {THUMB_LEFT,      10},
                              {THUMB_RIGHT,     -1},
                              {HAT_UP,          -1},
                              {THUMB_LEFT,      -1},
                              {HAT_UP,          -1},
                              {HAT_DOWN,        -1},
                              {HAT_LEFT,        -1},
                              {HAT_RIGHT,       -1},
                              {HOME,            -1}};

int btnState[20][2] =  {{BUTTON_0, 0},
                              {BUTTON_1, 0},
                              {BUTTON_2, 0},
                              {BUTTON_3, 0},
                              {SHOULDER_LEFT, 0},
                              {SHOULDER_RIGHT, 0},
                              {TRIGGER_LEFT, 0},
                              {TRIGGER_RIGHT, 0},
                              {START, 0},
                              {SELECT, 0},
                              {THUMB_LEFT, 0},
                              {THUMB_RIGHT, 0},
                              {HAT_UP, 0},
                              {THUMB_LEFT, 0},
                              {HAT_UP, 0},
                              {HAT_DOWN, 0},
                              {HAT_LEFT, 0},
                              {HAT_RIGHT, 0},
                              {HOME, 0}};

void loop() {
  for (int i = 0; i < 20; i++)  {
    if(pinToButtonMap[i][1] > -1) {
      int currentState = !digitalRead(pinToButtonMap[i][1]);
      if (currentState != btnState[i][1]) { // Detect button state change
        Joystick[0].setButton(i, currentState);
        Joystick[1].setButton(i, currentState);
        btnState[i][1] = currentState;
      }
    }
  }
  Joystick[0].setXAxis(analogRead(x1));
  Joystick[0].setYAxis(analogRead(y1));
  Joystick[1].setXAxis(analogRead(x2));
  Joystick[1].setYAxis(analogRead(y2));


   delay(50);
}

void currentState(uint32_t btnState, int8_t x1, int8_t y1, int8_t x2, int8_t 
y2)
{
  //write the header part for RN42
  Serial.write((uint8_t)0xFD); //start byte
  Serial.write((uint8_t)0x06); //length of the descriptor
  //gampad positions and buttons
  //on a gamepad there typically is two analog joysticks one is typically 
used to
  //indicate x/y position and one is for z/rotation. 
  Serial.write((uint8_t)x1 & 0xFF); //value between -127 to 127 indicating 
the x postition
  Serial.write((uint8_t)y1 & 0xFF); //value between -127 to 127 indicating 
the y postition
  Serial.write((uint8_t)x2 & 0xFF); //value between -127 to 127 indicating 
the z postition
  Serial.write((uint8_t)y2 & 0xFF); //value between -127 to 127 indicating 
the rotation postition
  //one bit for each button pressed there can be a total of 16 buttons one 
byte in each
  //set the bit to show a button pressed and clear the bit to indicate not 
pressed
  uint8_t btnState1 = btnState & 0xFF;
  uint8_t btnState2 = (btnState >> 8) & 0xFF;
  Serial.write((uint8_t)btnState1); 
  Serial.write((uint8_t)btnState2);
}

You are not matching the format of the report descriptor that the RN-42XV uses for HID Joystick reports. 您与RN-42XV用于HID游戏杆报告的报告描述符的格式不匹配。 The formats of supported HID reports are described in the Bluetooth Data Module Command Reference & Advanced Information User's Guide: 受支持的HID报告的格式在《蓝牙数据模块命令参考和高级信息用户指南》中进行了描述:

http://ww1.microchip.com/downloads/en/DeviceDoc/bluetooth_cr_UG-v1.0r.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/bluetooth_cr_UG-v1.0r.pdf

Section 5.3.3 describes the raw report format for joystick data: 第5.3.3节介绍了操纵杆数据的原始报告格式:

Byte 0: 0xFD (indicates raw HID report to follow) 字节0:0xFD(指示要遵循的原始HID报告)
Byte 1: 0x06 (report length) 字节1:0x06(报告长度)
Byte 2: State for buttons 0-7 字节2:按钮0-7的状态
Byte 3: State for buttons 8-15 字节3:按钮8-15的状态
Byte 4: Axis X1 字节4:轴X1
Byte 5: Axis Y1 字节5:轴Y1
Byte 6: Axis X2 字节6:轴X2
Byte 7: Axis Y2 字节7:轴Y2

Your currentState method is writing: 您的currentState方法正在编写:

Byte 0: 0xFD (good) 字节0:0xFD(良好)
Byte 1: 0x06 (good) 字节1:0x06(良好)
Byte 2: x1 & 0xFF (should be Buttons 0-7) 字节2:x1和0xFF(应为按钮0-7)
Byte 3: y1 & 0xFF (should be Buttons 8-15) 字节3:y1和0xFF(应为按钮8-15)
Byte 4: x2 & 0xFF (should be Axis X1) 字节4:x2和0xFF(应为轴X1)
Byte 5: y2 & 0xFF (should be Axis Y1) 字节5:y2和0xFF(应为轴Y1)
Byte 6: btnState & 0xFF (should be Axis X2) 字节6:btnState和0xFF(应为Axis X2)
Byte 7: (btnState >> 8) & 0xFF (should be Axis Y2) 字节7:(btnState >> 8)和0xFF(应为轴Y2)

I think it will work if you rearrange the method to write the button state before the axis state. 我认为,如果您重新安排在轴状态之前写入按钮状态的方法,它将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM