Bluetooth Arduino Геймпад
Я пытаюсь создать собственный контроллер Bluetooth с 2 аналоговыми джойстиками и 16 кнопками, используя чип RN-42XV Bluetooth и Arduino, который я могу использовать с Android и моим ПК с Windows. До сих пор я успешно кодировал Arduino Leonardo для работы в качестве игрового планшета с 2 аналоговыми джойстиками и 16 кнопками, но я не смог заставить Arduino работать с моим Bluetooth RN-42XV. RN-42XV подключается к моему компьютеру и отображается как геймпад с 2 аналоговыми джойстиками и 16 кнопками, но когда я нажимаю кнопки на Arduino, он не регистрируется на RN-42. Код, который я использую ниже, пожалуйста, помогите.
#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);
}
1 ответ
Вы не соответствует формату дескриптора отчета, который RN-42XV использует для отчетов HID Joystick. Форматы поддерживаемых отчетов HID описаны в Справочном руководстве по командам и расширенной информации модуля данных Bluetooth:
http://ww1.microchip.com/downloads/en/DeviceDoc/bluetooth_cr_UG-v1.0r.pdf
Раздел 5.3.3 описывает необработанный формат отчета для данных джойстика:
Байт 0: 0xFD (указывает на необработанный отчет HID, который должен следовать)
Байт 1: 0x06 (длина отчета)
Байт 2: состояние для кнопок 0-7
Байт 3: состояние для кнопок 8-15
Байт 4: Ось X1
Байт 5: ось Y1
Байт 6: Ось X2
Байт 7: ось Y2
Ваш метод currentState пишет:
Байт 0: 0xFD (хорошо)
Байт 1: 0x06 (хорошо)
Байт 2: x1 & 0xFF (должны быть кнопки 0-7)
Байт 3: y1 & 0xFF (должно быть кнопки 8-15)
Байт 4: x2 & 0xFF (должен быть Axis X1)
Байт 5: y2 & 0xFF (должно быть Ось Y1)
Байт 6: btnState & 0xFF (должен быть Axis X2)
Байт 7: (btnState >> 8) & 0xFF (должен быть Ось Y2)
Я думаю, что это будет работать, если вы переставите метод, чтобы записать состояние кнопки до состояния оси.