Esp32 HID gamepad project
Posted: Tue Jul 21, 2020 11:23 am
Hello!
Im trying to make a wireless gamecontroller. Im in a trouble, since im amateur in this field. I read a lot of similar project and i managed to make a code, which results a 2 axis, 8 buttons gamepad under win 10.
My problem is the data not sending to the PC.
Please check where did i screwd it!
Thank you if you spend some time on me!
Sandor
Im trying to make a wireless gamecontroller. Im in a trouble, since im amateur in this field. I read a lot of similar project and i managed to make a code, which results a 2 axis, 8 buttons gamepad under win 10.
My problem is the data not sending to the PC.
Please check where did i screwd it!
Thank you if you spend some time on me!
Sandor
Code: Select all
#include <Arduino.h>
#include<Math.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "BLE2902.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
#include <driver/adc.h>
BLEHIDDevice* hid;
BLECharacteristic* input;
BLECharacteristic* output;
#define NUM_BUTTONS 8 // you don't need to change this value
#define NUM_AXES 2 // 6 axes to UNO, and 8 to MEGA. If you are using UNO, don't need to change this value.
typedef struct joyReport_t {
int16_t axis[NUM_AXES];
uint8_t button[(NUM_BUTTONS+7)/8]; // 8 buttons per byte
} joyReport_t;
joyReport_t joyReport;
void setButton(joyReport_t *joy, uint8_t button);
void clearButton(joyReport_t *joy, uint8_t button);
void setButton(joyReport_t *joy, uint8_t button)
{
uint8_t index = button/8;
uint8_t bit = button - 8*index;
joy->button[index] |= 1 << bit;
//Serial.print("+");
// Serial.println(index);
}
// turn a button off
void clearButton(joyReport_t *joy, uint8_t button)
{
uint8_t index = button/8;
uint8_t bit = button - 8*index;
joy->button[index] &= ~(1 << bit);
// Serial.print("-");
}
bool connected = false;
class MyCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer){
connected = true;
BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(true);
}
void onDisconnect(BLEServer* pServer){
connected = false;
BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(true);
}
};
class MyOutputCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic* me){
uint8_t* value = (uint8_t*)(me->getValue().c_str());
ESP_LOGI(LOG_TAG, "special keys: %d", *value);
}
};
void taskServer(void*){
BLEDevice::init("Esp32 Joy");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyCallbacks());
hid = new BLEHIDDevice(pServer);
input = hid->inputReport(1); // <-- input REPORTID from report map
output = hid->outputReport(1); // <-- output REPORTID from report map
output->setCallbacks(new MyOutputCallbacks());
std::string name = "TestCo.";
hid->manufacturer()->setValue(name);
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
hid->hidInfo(0x00,0x02);
BLESecurity *pSecurity = new BLESecurity();
// pSecurity->setKeySize();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
const uint8_t report[] = {
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x05, /* Usage (Gamepad) */
0xa1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */
/* 8 axes, signed 16 bit resolution, range -32768 to 32767 (16 bytes) */
0xa1, 0x00, /* Collection (Physical) */
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
// 0x09, 0x32, /* Usage (Analog1) */
// 0x09, 0x33, /* Usage (Analog2) */
//0x09, 0x34, /* Usage (Analog3) */
//0x09, 0x35, /* Usage (Analog4) */
// 0x09, 0x36, /* Usage (Analog5) */
// 0x09, 0x37, /* Usage (Analog6) */
0x16, 0x00, 0x80, /* Logical Minimum (-32768) */
0x26, 0xff, 0x7f, /* Logical Maximum (32767) */
0x75, 16, /* Report Size (16) */
0x95, 2, /* Report Count (8) */
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
0xc0, /* End Collection */
/* 40 buttons, value 0=off, 1=on (5 bytes) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 1, /* Usage Minimum (Button 1) */
0x29, 8, /* Usage Maximum (Button 40) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 1, /* Report Size (1) */
0x95, 8, /* Report Count (40) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0xc0 /* End Collection */
};
hid->reportMap((uint8_t*)report, sizeof(report));
hid->startServices();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_GAMEPAD);
pAdvertising->addServiceUUID(hid->hidService()->getUUID());
pAdvertising->start();
hid->setBatteryLevel(34);
ESP_LOGD(LOG_TAG, "Advertising started!");
delay(portMAX_DELAY);
};
void setup() {
Serial.begin(115200);
//Serial.println("Starting BLE work!");
for (uint8_t ind=0; ind<NUM_AXES; ind++) {
joyReport.axis[ind] = ind*0;
}
for (uint8_t ind=0; ind<NUM_BUTTONS; ind++) {
joyReport.button[ind] = 0;
}
xTaskCreate(taskServer, "server", 20000, NULL, 5, NULL);
}
void loop() {
if (connected) {
for (uint8_t ind=0; ind<NUM_AXES; ind++) {
joyReport.axis[ind] = random(-2000, 2000);
//Serial.println(joyReport.axis[ind]);
}
for (uint8_t ind=0; ind<NUM_BUTTONS; ind++) {
uint8_t buttonval;
buttonval = random(0,2);
// Serial.print(buttonval);
if (buttonval == 1) {
setButton(&joyReport, ind);
}
else {
clearButton(&joyReport, ind);
}
//random(0,1);
}
// Serial.println();
Serial.println(joyReport.axis[0]);
Serial.println(joyReport.axis[1]);
Serial.println(joyReport.button[0], BIN);
// Serial.println("-------------------------------");
// Serial.println(sizeof(joyReport));
// Serial.println((NUM_BUTTONS+7)/8);
//Serial.println("-------------------------------");
input->setValue((uint8_t*)&joyReport,sizeof(joyReport));
input->notify();
}
delay(10);
}