From 3018600dbd6b1d4246268a5ba86c94bb3e3253d3 Mon Sep 17 00:00:00 2001 From: lemmingDev Date: Sat, 28 Nov 2020 13:43:27 +1000 Subject: [PATCH] 32 buttons and X,Y,Z and rZ axes are now 16 bit Library now supports 32 buttons X,Y,Z and rZ axes are now 16 bit int16_t (-32767 to 32767) instead of 8 bit (-127 to 127) If you're upgrading, remember to account for this when setting your axes values --- BleGamepad.cpp | 82 ++++++++++++++------------ BleGamepad.h | 28 +++++++-- README.md | 16 ++--- examples/Gamepad/Gamepad.ino | 21 ++++--- examples/PotAsAxis/PotAsAxis.ino | 4 +- examples/SingleButton/SingleButton.ino | 11 ++-- keywords.txt | 40 +++++++++---- library.properties | 4 +- 8 files changed, 128 insertions(+), 78 deletions(-) diff --git a/BleGamepad.cpp b/BleGamepad.cpp index 581e9ac..33456f3 100644 --- a/BleGamepad.cpp +++ b/BleGamepad.cpp @@ -26,40 +26,37 @@ static const uint8_t _hidReportDescriptor[] = { USAGE(1), 0x01, // USAGE (Pointer) COLLECTION(1), 0x00, // COLLECTION (Physical) - // ------------------------------------------------- Buttons (1 to 14) + // ------------------------------------------------- Buttons (1 to 32) USAGE_PAGE(1), 0x09, // USAGE_PAGE (Button) USAGE_MINIMUM(1), 0x01, // USAGE_MINIMUM (Button 1) - USAGE_MAXIMUM(1), 0x0e, // USAGE_MAXIMUM (Button 14) + USAGE_MAXIMUM(1), 0x20, // USAGE_MAXIMUM (Button 32) LOGICAL_MINIMUM(1), 0x00, // LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM(1), 0x01, // LOGICAL_MAXIMUM (1) REPORT_SIZE(1), 0x01, // REPORT_SIZE (1) - REPORT_COUNT(1), 0x0e, // REPORT_COUNT (14) - HIDINPUT(1), 0x02, // INPUT (Data, Variable, Absolute) ;14 button bits - // ------------------------------------------------- Padding - REPORT_SIZE(1), 0x01, // REPORT_SIZE (1) - REPORT_COUNT(1), 0x02, // REPORT_COUNT (2) - HIDINPUT(1), 0x03, // INPUT (Constant, Variable, Absolute) ;2 bit padding + REPORT_COUNT(1), 0x20, // REPORT_COUNT (32) + HIDINPUT(1), 0x02, // INPUT (Data, Variable, Absolute) ;32 button bits // ------------------------------------------------- X/Y position, Z/rZ position - USAGE_PAGE(1), 0x01, // USAGE_PAGE (Generic Desktop) - USAGE(1), 0x30, // USAGE (X) - USAGE(1), 0x31, // USAGE (Y) - USAGE(1), 0x32, // USAGE (Z) - USAGE(1), 0x35, // USAGE (rZ) - LOGICAL_MINIMUM(1), 0x81, // LOGICAL_MINIMUM (-127) - LOGICAL_MAXIMUM(1), 0x7f, // LOGICAL_MAXIMUM (127) - REPORT_SIZE(1), 0x08, // REPORT_SIZE (8) - REPORT_COUNT(1), 0x04, // REPORT_COUNT (4) - HIDINPUT(1), 0x02, // INPUT (Data, Variable, Absolute) ;4 bytes (X,Y,Z,rZ) - - USAGE_PAGE(1), 0x01, // USAGE_PAGE (Generic Desktop) + USAGE_PAGE(1), 0x01, // USAGE_PAGE (Generic Desktop) + COLLECTION(1), 0x00, // COLLECTION (Physical) + USAGE(1), 0x30, // USAGE (X) + USAGE(1), 0x31, // USAGE (Y) + USAGE(1), 0x32, // USAGE (Z) + USAGE(1), 0x35, // USAGE (rZ) + 0x16, 0x01, 0x80,//LOGICAL_MINIMUM (-32767) + 0x26, 0xFF, 0x7F,//LOGICAL_MAXIMUM (32767) + REPORT_SIZE(1), 0x10, // REPORT_SIZE (16) + REPORT_COUNT(1), 0x04, // REPORT_COUNT (4) + HIDINPUT(1), 0x02, // INPUT (Data,Var,Abs) + // ------------------------------------------------- Triggers USAGE(1), 0x33, // USAGE (rX) Left Trigger USAGE(1), 0x34, // USAGE (rY) Right Trigger LOGICAL_MINIMUM(1), 0x81, // LOGICAL_MINIMUM (-127) LOGICAL_MAXIMUM(1), 0x7f, // LOGICAL_MAXIMUM (127) REPORT_SIZE(1), 0x08, // REPORT_SIZE (8) REPORT_COUNT(1), 0x02, // REPORT_COUNT (2) - HIDINPUT(1), 0x02, // INPUT (Data, Variable, Absolute) ;2 bytes rX, rY - + HIDINPUT(1), 0x02, // INPUT (Data, Variable, Absolute) ;4 bytes (X,Y,Z,rZ) + END_COLLECTION(0), // END_COLLECTION + USAGE_PAGE(1), 0x01, // USAGE_PAGE (Generic Desktop) USAGE(1), 0x39, // USAGE (Hat switch) USAGE(1), 0x39, // USAGE (Hat switch) @@ -92,28 +89,39 @@ void BleGamepad::end(void) { } -void BleGamepad::setAxes(signed char x, signed char y, signed char z, signed char rZ, char rX, char rY, signed char hat) +void BleGamepad::setAxes(int16_t x, int16_t y, int16_t z, int16_t rZ, char rX, char rY, signed char hat) { if (this->isConnected()) { - uint8_t m[9]; + if(x == -32768) { x = -32767; } + if(y == -32768) { y = -32767; } + if(z == -32768) { z = -32767; } + if(rZ == -32768) { rZ = -32767; } + + uint8_t m[15]; m[0] = _buttons; m[1] = (_buttons >> 8); - m[2] = x; - m[3] = y; - m[4] = z; - m[5] = rZ; - m[6] = (signed char)(rX - 128); - m[7] = (signed char)(rY - 128); - m[8] = hat; - if (m[6] == -128) { m[6] = -127; } - if (m[7] == -128) { m[7] = -127; } + m[2] = (_buttons >> 16); + m[3] = (_buttons >> 24); + m[4] = x; + m[5] = (x >> 8); + m[6] = y; + m[7] = (y >> 8); + m[8] = z; + m[9] = (z >> 8); + m[10] = rZ; + m[11] = (rZ >> 8); + m[12] = (signed char)(rX - 128); + m[13] = (signed char)(rY - 128); + m[14] = hat; + if (m[12] == -128) { m[12] = -127; } + if (m[13] == -128) { m[13] = -127; } this->inputGamepad->setValue(m, sizeof(m)); this->inputGamepad->notify(); } } -void BleGamepad::buttons(uint16_t b) +void BleGamepad::buttons(uint32_t b) { if (b != _buttons) { @@ -122,17 +130,17 @@ void BleGamepad::buttons(uint16_t b) } } -void BleGamepad::press(uint16_t b) +void BleGamepad::press(uint32_t b) { buttons(_buttons | b); } -void BleGamepad::release(uint16_t b) +void BleGamepad::release(uint32_t b) { buttons(_buttons & ~b); } -bool BleGamepad::isPressed(uint16_t b) +bool BleGamepad::isPressed(uint32_t b) { if ((b & _buttons) > 0) return true; diff --git a/BleGamepad.h b/BleGamepad.h index f6390ab..ac5f207 100644 --- a/BleGamepad.h +++ b/BleGamepad.h @@ -21,6 +21,24 @@ #define BUTTON_12 2048 #define BUTTON_13 4096 #define BUTTON_14 8192 +#define BUTTON_15 16384 +#define BUTTON_16 32768 +#define BUTTON_17 65536 +#define BUTTON_18 131072 +#define BUTTON_19 262144 +#define BUTTON_20 524288 +#define BUTTON_21 1048576 +#define BUTTON_22 2097152 +#define BUTTON_23 4194304 +#define BUTTON_24 8388608 +#define BUTTON_25 16777216 +#define BUTTON_26 33554432 +#define BUTTON_27 67108864 +#define BUTTON_28 134217728 +#define BUTTON_29 268435456 +#define BUTTON_30 536870912 +#define BUTTON_31 1073741824 +#define BUTTON_32 2147483648 #define DPAD_CENTERED 0 #define DPAD_UP 1 @@ -38,17 +56,17 @@ class BleGamepad { BleConnectionStatus* connectionStatus; BLEHIDDevice* hid; BLECharacteristic* inputGamepad; - void buttons(uint16_t b); + void buttons(uint32_t b); void rawAction(uint8_t msg[], char msgSize); static void taskServer(void* pvParameter); public: BleGamepad(std::string deviceName = "ESP32 BLE Gamepad", std::string deviceManufacturer = "Espressif", uint8_t batteryLevel = 100); void begin(void); void end(void); - void setAxes(signed char x, signed char y, signed char z = 0, signed char rZ = 0, char rX = 0, char rY = 0, signed char hat = 0); - void press(uint16_t b = BUTTON_1); // press BUTTON_1 by default - void release(uint16_t b = BUTTON_1); // release BUTTON_1 by default - bool isPressed(uint16_t b = BUTTON_1); // check BUTTON_1 by default + void setAxes(int16_t x, int16_t y, int16_t z = 0, int16_t rZ = 0, char rX = 0, char rY = 0, signed char hat = 0); + void press(uint32_t b = BUTTON_1); // press BUTTON_1 by default + void release(uint32_t b = BUTTON_1); // release BUTTON_1 by default + bool isPressed(uint32_t b = BUTTON_1); // check BUTTON_1 by default bool isConnected(void); void setBatteryLevel(uint8_t level); uint8_t batteryLevel; diff --git a/README.md b/README.md index 2430dbe..92afbb7 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ This library allows you to make the ESP32 act as a Bluetooth Gamepad and control ## Features - - [x] Button press (14 buttons) - - [x] Button release (14 buttons) + - [x] Button press (32 buttons) + - [x] Button release (32 buttons) - [x] Axes movement (6 axes (x, y, z, rZ, rX, rY) --> (Left Thumb X, Left Thumb Y, Right Thumb X, Right Thumb Y, Left Trigger, Right Trigger))) - [x] Point of view hat (d-pad) - [x] Report optional battery level to host (basically works, but it doesn't show up in Android's status bar) @@ -30,13 +30,13 @@ This library allows you to make the ESP32 act as a Bluetooth Gamepad and control * This example turns the ESP32 into a Bluetooth LE gamepad that presses buttons and moves axis * * Possible buttons are: - * BUTTON_1 through to BUTTON_14 + * BUTTON_1 through to BUTTON_32 * * Possible DPAD/HAT switch position values are: * DPAD_CENTERED, DPAD_UP, DPAD_UP_RIGHT, DPAD_RIGHT, DPAD_DOWN_RIGHT, * DPAD_DOWN, DPAD_DOWN_LEFT, DPAD_LEFT, DPAD_UP_LEFT * - * bleGamepad.setAxes takes the following signed char parameters for the Left/Right Thumb X/Y, char for the Left/Right Triggers, and hat switch position as above: + * bleGamepad.setAxes takes the following int16_t parameters for the Left/Right Thumb X/Y, char for the Left/Right Triggers, and hat switch position as above: * (Left Thumb X, Left Thumb Y, Right Thumb X, Right Thumb Y, Left Trigger, Right Trigger, Hat switch position); */ @@ -52,15 +52,15 @@ void setup() { void loop() { if(bleGamepad.isConnected()) { - Serial.println("Press buttons 1 and 14. Move all axes to max. Set DPAD to down right."); + Serial.println("Press buttons 1 and 32. Move all axes to max. Set DPAD to down right."); bleGamepad.press(BUTTON_1); - bleGamepad.press(BUTTON_14); - bleGamepad.setAxes(127, 127, 127, 127, 255, 255, DPAD_DOWN_RIGHT); + bleGamepad.press(BUTTON_32); + bleGamepad.setAxes(32767, 32767, 32767, 32767, 255, 255, DPAD_DOWN_RIGHT); delay(500); Serial.println("Release button 1. Move all axes to min. Set DPAD to centred."); bleGamepad.release(BUTTON_1); - bleGamepad.setAxes(-127, -127, -127, -127, 0, 0, DPAD_CENTERED); + bleGamepad.setAxes(-32767, -32767, -32767, -32767, 0, 0, DPAD_CENTERED); delay(500); } } diff --git a/examples/Gamepad/Gamepad.ino b/examples/Gamepad/Gamepad.ino index 2e5f22d..42f870a 100644 --- a/examples/Gamepad/Gamepad.ino +++ b/examples/Gamepad/Gamepad.ino @@ -2,13 +2,13 @@ * This example turns the ESP32 into a Bluetooth LE gamepad that presses buttons and moves axis * * Possible buttons are: - * BUTTON_1 through to BUTTON_14 + * BUTTON_1 through to BUTTON_32 * * Possible DPAD/HAT switch position values are: * DPAD_CENTERED, DPAD_UP, DPAD_UP_RIGHT, DPAD_RIGHT, DPAD_DOWN_RIGHT, * DPAD_DOWN, DPAD_DOWN_LEFT, DPAD_LEFT, DPAD_UP_LEFT * - * bleGamepad.setAxes takes the following signed char parameters for the Left/Right Thumb X/Y, char for the Left/Right Triggers, and hat switch position as above: + * bleGamepad.setAxes takes the following int16_t parameters for the Left/Right Thumb X/Y, char for the Left/Right Triggers, and hat switch position as above: * (Left Thumb X, Left Thumb Y, Right Thumb X, Right Thumb Y, Left Trigger, Right Trigger, Hat switch position); */ @@ -16,23 +16,26 @@ BleGamepad bleGamepad; -void setup() { +void setup() +{ Serial.begin(115200); Serial.println("Starting BLE work!"); bleGamepad.begin(); } -void loop() { - if(bleGamepad.isConnected()) { - Serial.println("Press buttons 1 and 14. Move all axes to max. Set DPAD to down right."); +void loop() +{ + if(bleGamepad.isConnected()) + { + Serial.println("Press buttons 1 and 32. Move all axes to max. Set DPAD to down right."); bleGamepad.press(BUTTON_1); - bleGamepad.press(BUTTON_14); - bleGamepad.setAxes(127, 127, 127, 127, 255, 255, DPAD_DOWN_RIGHT); + bleGamepad.press(BUTTON_32); + bleGamepad.setAxes(32767, 32767, 32767, 32767, 255, 255, DPAD_DOWN_RIGHT); delay(500); Serial.println("Release button 1. Move all axes to min. Set DPAD to centred."); bleGamepad.release(BUTTON_1); - bleGamepad.setAxes(-127, -127, -127, -127, 0, 0, DPAD_CENTERED); + bleGamepad.setAxes(-32767, -32767, -32767, -32767, 0, 0, DPAD_CENTERED); delay(500); } } \ No newline at end of file diff --git a/examples/PotAsAxis/PotAsAxis.ino b/examples/PotAsAxis/PotAsAxis.ino index 9d9d4f0..7e08ce1 100644 --- a/examples/PotAsAxis/PotAsAxis.ino +++ b/examples/PotAsAxis/PotAsAxis.ino @@ -45,8 +45,8 @@ void loop() // Calculate the average potValue = potValue / numberOfPotSamples; - // Map analog reading from 0 ~ 4095 to 127 ~ -127 for use as an axis reading - int adjustedValue = map(potValue, 0, 4095, 127, -127); + // Map analog reading from 0 ~ 4095 to 32737 ~ -32737 for use as an axis reading + int adjustedValue = map(potValue, 0, 4095, 32737, -32737); // Print readings to serial port Serial.print("Sent: "); diff --git a/examples/SingleButton/SingleButton.ino b/examples/SingleButton/SingleButton.ino index 01a0f17..ae48ad2 100644 --- a/examples/SingleButton/SingleButton.ino +++ b/examples/SingleButton/SingleButton.ino @@ -2,19 +2,22 @@ * A simple sketch that maps a single pin on the ESP32 to a single button on the controller */ -#include +#include // https://github.com/lemmingDev/ESP32-BLE-Gamepad BleGamepad bleGamepad; int previousButton1State = HIGH; -void setup() { +void setup() +{ pinMode(2, INPUT_PULLUP); bleGamepad.begin(); } -void loop() { - if(bleGamepad.isConnected()) { +void loop() +{ + if(bleGamepad.isConnected()) + { int currentButton1State = digitalRead(2); diff --git a/keywords.txt b/keywords.txt index a05187b..dad7363 100644 --- a/keywords.txt +++ b/keywords.txt @@ -10,11 +10,11 @@ BleGamepad KEYWORD1 # Methods and Functions ####################################### -begin KEYWORD2 -end KEYWORD2 -setAxes KEYWORD2 -press KEYWORD2 -release KEYWORD2 +begin KEYWORD2 +end KEYWORD2 +setAxes KEYWORD2 +press KEYWORD2 +release KEYWORD2 isPressed KEYWORD2 isConnected KEYWORD2 @@ -36,13 +36,31 @@ BUTTON_11 LITERAL1 BUTTON_12 LITERAL1 BUTTON_13 LITERAL1 BUTTON_14 LITERAL1 +BUTTON_15 LITERAL1 +BUTTON_16 LITERAL1 +BUTTON_17 LITERAL1 +BUTTON_18 LITERAL1 +BUTTON_19 LITERAL1 +BUTTON_20 LITERAL1 +BUTTON_21 LITERAL1 +BUTTON_22 LITERAL1 +BUTTON_23 LITERAL1 +BUTTON_24 LITERAL1 +BUTTON_25 LITERAL1 +BUTTON_26 LITERAL1 +BUTTON_27 LITERAL1 +BUTTON_28 LITERAL1 +BUTTON_29 LITERAL1 +BUTTON_30 LITERAL1 +BUTTON_31 LITERAL1 +BUTTON_32 LITERAL1 DPAD_CENTERED LITERAL1 -DPAD_UP LITERAL1 +DPAD_UP LITERAL1 DPAD_UP_RIGHT LITERAL1 -DPAD_RIGHT LITERAL1 -DPAD_DOWN_RIGHT LITERAL1 -DPAD_DOWN LITERAL1 +DPAD_RIGHT LITERAL1 +DPAD_DOWN_RIGHT LITERAL1 +DPAD_DOWN LITERAL1 DPAD_DOWN_LEFT LITERAL1 -DPAD_LEFT LITERAL1 -DPAD_UP_LEFT LITERAL1 +DPAD_LEFT LITERAL1 +DPAD_UP_LEFT LITERAL1 \ No newline at end of file diff --git a/library.properties b/library.properties index e2ffc07..d6735bf 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=ESP32 BLE Gamepad -version=0.1.3 +version=0.1.4 author=lemmingDev maintainer=lemmingDev sentence=Bluetooth LE Gamepad library for the ESP32. paragraph=Bluetooth LE Gamepad library for the ESP32. category=Communication url=https://github.com/lemmingDev/ESP32-BLE-Gamepad -architectures=esp32 +architectures=esp32 \ No newline at end of file