I have been working on using ESP32-C3 Super Mini to function as a button box using bluetooth.
I have managed to get the device to be able to connect via bluetooth to my pc and I can see a new game controller. However when I test the button presses its seems none of the buttons are working. I am fairly sure the wiring is correct and it has a good power supply so believe its the code.
Any help would be greatly appreciated!
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLEHIDDevice.h>
#include <HIDTypes.h>
#include <HIDKeyboardTypes.h>
#define SERVICE_UUID "1812"
#define CHARACTERISTIC_UUID "2A4D"
int buttonPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 20, 21};
int lastState[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t report[2] = {0b00000000, 0b00000000};
BLEHIDDevice* hid;
BLECharacteristic* input;
BLECharacteristic* output;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("Client connected");
}
void onDisconnect(BLEServer* pServer) {
Serial.println("Client disconnected, restarting advertising in 2 seconds...");
delay(2000);
BLEDevice::startAdvertising();
}
};
void setup() {
Serial.begin(115200);
Serial.println("Initializing BLE...");
for (int i = 0; i < 10; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
BLEDevice::init("Tims wheel"); // Set your custom device name
BLEServer* pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
hid = new BLEHIDDevice(pServer);
input = hid->inputReport(1);
output = hid->outputReport(1);
// Set security parameters
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND); // Use bonding and secure connections
pSecurity->setCapability(ESP_IO_CAP_NONE); // No input/output capabilities
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
hid->manufacturer()->setValue("TLSolutions");
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
hid->hidInfo(0x00, 0x01);
const uint8_t reportMap[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x05, // Usage (Gamepad)
0xA1, 0x01, // Collection (Application)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1)
0x29, 0x10, // Usage Maximum (Button 16)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x10, // Report Count (16)
0x81, 0x02, // Input (Data, Variable, Absolute)
0xC0, // End Collection
0xC0 // End Collection
};
hid->reportMap((uint8_t*)reportMap, sizeof(reportMap));
hid->startServices();
BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setAppearance(HID_GAMEPAD);
pAdvertising->addServiceUUID(hid->hidService()->getUUID());
pAdvertising->setMinInterval(0x20); // Minimum advertising interval (32 * 0.625ms)
pAdvertising->setMaxInterval(0x40); // Maximum advertising interval (64 * 0.625ms)
pAdvertising->setScanResponse(true);
pAdvertising->start();
Serial.println("BLE Gamepad is advertising continuously!");
}
void loop() {
for (int i = 0; i < 10; i++) {
int currentState = !digitalRead(buttonPins[i]);
if (currentState != lastState[i]) {
lastState[i] = currentState;
if (currentState) {
report[i / 8] |= (1 << (i % 8)); // Set bit
Serial.print("Button "); Serial.print(i); Serial.println(" pressed");
} else {
report[i / 8] &= ~(1 << (i % 8)); // Clear bit
Serial.print("Button "); Serial.print(i); Serial.println(" released");
}d
}
}
static unsigned long lastNotifyTime = 0;
unsigned long currentTime = millis();
if (currentTime - lastNotifyTime > 100) { // 100 ms interval
input->setValue(report, sizeof(report));
input->notify();
lastNotifyTime = currentTime;
Serial.println("Report sent");
}
delay(10); // Debounce delay
}